summaryrefslogtreecommitdiff
path: root/test/Analysis
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-07-23 20:41:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-07-23 20:41:05 +0000
commit01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch)
tree4def12e759965de927d963ac65840d663ef9d1ea /test/Analysis
parentf0f4822ed4b66e3579e92a89f368f8fb860e218e (diff)
Notes
Diffstat (limited to 'test/Analysis')
-rw-r--r--test/Analysis/BasicAA/cs-cs.ll43
-rw-r--r--test/Analysis/BasicAA/guards.ll30
-rw-r--r--test/Analysis/BasicAA/negoffset.ll98
-rw-r--r--test/Analysis/BasicAA/noalias-wraparound-bug.ll24
-rw-r--r--test/Analysis/BasicAA/phi-aa.ll1
-rw-r--r--test/Analysis/BasicAA/returned.ll45
-rw-r--r--test/Analysis/BasicAA/struct-geps.ll9
-rw-r--r--test/Analysis/BlockFrequencyInfo/bad_input.ll1
-rw-r--r--test/Analysis/BlockFrequencyInfo/basic.ll2
-rw-r--r--test/Analysis/BlockFrequencyInfo/double_backedge.ll1
-rw-r--r--test/Analysis/BlockFrequencyInfo/double_exit.ll1
-rw-r--r--test/Analysis/BlockFrequencyInfo/extremely-likely-loop-successor.ll1
-rw-r--r--test/Analysis/BlockFrequencyInfo/irreducible.ll1
-rw-r--r--test/Analysis/BlockFrequencyInfo/irreducible_loop_crash.ll1
-rw-r--r--test/Analysis/BlockFrequencyInfo/loop_with_branch.ll1
-rw-r--r--test/Analysis/BlockFrequencyInfo/loops_with_profile_info.ll1
-rw-r--r--test/Analysis/BlockFrequencyInfo/nested_loop_with_branches.ll1
-rw-r--r--test/Analysis/BranchProbabilityInfo/basic.ll1
-rw-r--r--test/Analysis/BranchProbabilityInfo/deopt-intrinsic.ll21
-rw-r--r--test/Analysis/BranchProbabilityInfo/loop.ll1
-rw-r--r--test/Analysis/BranchProbabilityInfo/noreturn.ll1
-rw-r--r--test/Analysis/BranchProbabilityInfo/pr18705.ll1
-rw-r--r--test/Analysis/BranchProbabilityInfo/pr22718.ll1
-rw-r--r--test/Analysis/CFLAliasAnalysis/Andersen/assign.ll24
-rw-r--r--test/Analysis/CFLAliasAnalysis/Andersen/assign2.ll23
-rw-r--r--test/Analysis/CFLAliasAnalysis/Andersen/attrs-below.ll61
-rw-r--r--test/Analysis/CFLAliasAnalysis/Andersen/attrs.ll94
-rw-r--r--test/Analysis/CFLAliasAnalysis/Andersen/cycle.ll34
-rw-r--r--test/Analysis/CFLAliasAnalysis/Andersen/memalias.ll21
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/arguments-globals.ll (renamed from test/Analysis/CFLAliasAnalysis/arguments-globals.ll)2
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/arguments.ll (renamed from test/Analysis/CFLAliasAnalysis/arguments.ll)2
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/asm-global-bugfix.ll (renamed from test/Analysis/CFLAliasAnalysis/asm-global-bugfix.ll)2
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/attr-escape.ll94
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/basic-interproc.ll22
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/branch-alias.ll (renamed from test/Analysis/CFLAliasAnalysis/branch-alias.ll)2
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/const-expr-gep.ll (renamed from test/Analysis/CFLAliasAnalysis/const-expr-gep.ll)8
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/constant-over-index.ll (renamed from test/Analysis/CFLAliasAnalysis/constant-over-index.ll)2
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/empty.ll (renamed from test/Analysis/CFLAliasAnalysis/empty.ll)2
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/full-store-partial-alias.ll (renamed from test/Analysis/CFLAliasAnalysis/full-store-partial-alias.ll)8
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/gep-index-no-alias.ll14
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/gep-signed-arithmetic.ll (renamed from test/Analysis/CFLAliasAnalysis/gep-signed-arithmetic.ll)4
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-arg-deref-escape.ll33
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-arg-escape.ll31
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-arg.ll23
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-deref-arg-multilevel.ll46
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-deref-arg.ll30
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-escape.ll33
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-ref-arg-multilevel.ll51
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-ref-arg.ll36
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-unknown.ll38
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-store-arg-multilevel.ll48
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-store-arg-unknown.ll32
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-store-arg.ll36
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/malloc-and-free.ll30
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/multilevel-combine.ll (renamed from test/Analysis/CFLAliasAnalysis/multilevel-combine.ll)2
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/multilevel.ll (renamed from test/Analysis/CFLAliasAnalysis/multilevel.ll)2
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/must-and-partial.ll (renamed from test/Analysis/CFLAliasAnalysis/must-and-partial.ll)6
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/opaque-call-alias.ll (renamed from test/Analysis/CFLAliasAnalysis/opaque-call-alias.ll)4
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/phi-and-select.ll (renamed from test/Analysis/CFLAliasAnalysis/phi-and-select.ll)2
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/pr27213.ll39
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/simple.ll (renamed from test/Analysis/CFLAliasAnalysis/simple.ll)4
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/stratified-attrs-indexing.ll (renamed from test/Analysis/CFLAliasAnalysis/stratified-attrs-indexing.ll)4
-rw-r--r--test/Analysis/CFLAliasAnalysis/Steensgaard/va.ll (renamed from test/Analysis/CFLAliasAnalysis/va.ll)15
-rw-r--r--test/Analysis/CFLAliasAnalysis/basic-interproc-ret.ll26
-rw-r--r--test/Analysis/CFLAliasAnalysis/basic-interproc.ll24
-rw-r--r--test/Analysis/CallGraph/no-intrinsics.ll1
-rw-r--r--test/Analysis/CostModel/AArch64/kryo.ll26
-rw-r--r--test/Analysis/CostModel/AMDGPU/add-sub.ll138
-rw-r--r--test/Analysis/CostModel/AMDGPU/addrspacecast.ll45
-rw-r--r--test/Analysis/CostModel/AMDGPU/bit-ops.ll59
-rw-r--r--test/Analysis/CostModel/AMDGPU/fabs.ll97
-rw-r--r--test/Analysis/CostModel/AMDGPU/fadd.ll88
-rw-r--r--test/Analysis/CostModel/AMDGPU/fdiv.ll96
-rw-r--r--test/Analysis/CostModel/AMDGPU/fmul.ll88
-rw-r--r--test/Analysis/CostModel/AMDGPU/fsub.ll86
-rw-r--r--test/Analysis/CostModel/AMDGPU/insertelement.ll37
-rw-r--r--test/Analysis/CostModel/AMDGPU/mul.ll85
-rw-r--r--test/Analysis/CostModel/AMDGPU/shifts.ll61
-rw-r--r--test/Analysis/CostModel/ARM/cast.ll176
-rw-r--r--test/Analysis/CostModel/PowerPC/ext.ll2
-rw-r--r--test/Analysis/CostModel/PowerPC/load_store.ll2
-rw-r--r--test/Analysis/CostModel/PowerPC/popcnt.ll11
-rw-r--r--test/Analysis/CostModel/X86/arith.ll207
-rw-r--r--test/Analysis/CostModel/X86/bitreverse.ll157
-rw-r--r--test/Analysis/CostModel/X86/bswap.ll82
-rw-r--r--test/Analysis/CostModel/X86/cast.ll18
-rw-r--r--test/Analysis/CostModel/X86/cmp.ll146
-rw-r--r--test/Analysis/CostModel/X86/ctbits-cost.ll567
-rw-r--r--test/Analysis/CostModel/X86/masked-intrinsic-cost.ll56
-rw-r--r--test/Analysis/CostModel/X86/scalarize.ll24
-rw-r--r--test/Analysis/CostModel/X86/sitofp.ll136
-rw-r--r--test/Analysis/CostModel/X86/sse-itoi.ll81
-rw-r--r--test/Analysis/CostModel/X86/uitofp.ll142
-rw-r--r--test/Analysis/DemandedBits/basic.ll4
-rw-r--r--test/Analysis/DependenceAnalysis/MIVCheckConst.ll73
-rw-r--r--test/Analysis/DivergenceAnalysis/AMDGPU/atomics.ll15
-rw-r--r--test/Analysis/DivergenceAnalysis/AMDGPU/interp-intrinsics.ll22
-rw-r--r--test/Analysis/DivergenceAnalysis/AMDGPU/kernel-args.ll4
-rw-r--r--test/Analysis/DivergenceAnalysis/AMDGPU/llvm.amdgcn.buffer.atomic.ll103
-rw-r--r--test/Analysis/DivergenceAnalysis/AMDGPU/llvm.amdgcn.image.atomic.ll121
-rw-r--r--test/Analysis/DivergenceAnalysis/AMDGPU/no-return-blocks.ll30
-rw-r--r--test/Analysis/DivergenceAnalysis/AMDGPU/phi-undef.ll28
-rw-r--r--test/Analysis/DivergenceAnalysis/AMDGPU/unreachable-loop-block.ll17
-rw-r--r--test/Analysis/DivergenceAnalysis/AMDGPU/workitem-intrinsics.ll45
-rw-r--r--test/Analysis/DivergenceAnalysis/NVPTX/diverge.ll4
-rw-r--r--test/Analysis/DominanceFrontier/new_pm_test.ll50
-rw-r--r--test/Analysis/GlobalsModRef/aliastest.ll1
-rw-r--r--test/Analysis/GlobalsModRef/comdat-ipo.ll21
-rw-r--r--test/Analysis/GlobalsModRef/func-memattributes.ll31
-rw-r--r--test/Analysis/GlobalsModRef/indirect-global.ll1
-rw-r--r--test/Analysis/GlobalsModRef/no-escape.ll65
-rw-r--r--test/Analysis/LazyCallGraph/basic.ll281
-rw-r--r--test/Analysis/LazyCallGraph/non-leaf-intrinsics.ll6
-rw-r--r--test/Analysis/LoopAccessAnalysis/backward-dep-different-types.ll1
-rw-r--r--test/Analysis/LoopAccessAnalysis/forward-loop-carried.ll1
-rw-r--r--test/Analysis/LoopAccessAnalysis/forward-loop-independent.ll1
-rw-r--r--test/Analysis/LoopAccessAnalysis/independent-interleaved.ll46
-rw-r--r--test/Analysis/LoopAccessAnalysis/memcheck-for-loop-invariant.ll39
-rw-r--r--test/Analysis/LoopAccessAnalysis/multiple-strides-rt-memory-checks.ll68
-rw-r--r--test/Analysis/LoopAccessAnalysis/non-wrapping-pointer.ll1
-rw-r--r--test/Analysis/LoopAccessAnalysis/nullptr.ll1
-rw-r--r--test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll11
-rw-r--r--test/Analysis/LoopAccessAnalysis/pointer-with-unknown-bounds.ll1
-rw-r--r--test/Analysis/LoopAccessAnalysis/resort-to-memchecks-only.ll1
-rw-r--r--test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll5
-rw-r--r--test/Analysis/LoopAccessAnalysis/safe-no-checks.ll1
-rw-r--r--test/Analysis/LoopAccessAnalysis/safe-with-dep-distance.ll38
-rw-r--r--test/Analysis/LoopAccessAnalysis/store-to-invariant-check1.ll16
-rw-r--r--test/Analysis/LoopAccessAnalysis/store-to-invariant-check2.ll1
-rw-r--r--test/Analysis/LoopAccessAnalysis/store-to-invariant-check3.ll1
-rw-r--r--test/Analysis/LoopAccessAnalysis/stride-access-dependence.ll3
-rw-r--r--test/Analysis/LoopAccessAnalysis/underlying-objects-1.ll1
-rw-r--r--test/Analysis/LoopAccessAnalysis/underlying-objects-2.ll1
-rw-r--r--test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks.ll1
-rw-r--r--test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll429
-rw-r--r--test/Analysis/PostDominators/pr1098.ll1
-rw-r--r--test/Analysis/ProfileSummary/basic.ll39
-rw-r--r--test/Analysis/RegionInfo/20100809_bb_not_in_domtree.ll2
-rw-r--r--test/Analysis/RegionInfo/block_sort.ll2
-rw-r--r--test/Analysis/RegionInfo/cond_loop.ll2
-rw-r--r--test/Analysis/RegionInfo/condition_complicated.ll2
-rw-r--r--test/Analysis/RegionInfo/condition_complicated_2.ll2
-rw-r--r--test/Analysis/RegionInfo/condition_forward_edge.ll2
-rw-r--r--test/Analysis/RegionInfo/condition_same_exit.ll2
-rw-r--r--test/Analysis/RegionInfo/condition_simple.ll2
-rw-r--r--test/Analysis/RegionInfo/exit_in_condition.ll2
-rw-r--r--test/Analysis/RegionInfo/loop_with_condition.ll2
-rw-r--r--test/Analysis/RegionInfo/loops_1.ll2
-rw-r--r--test/Analysis/RegionInfo/loops_2.ll2
-rw-r--r--test/Analysis/RegionInfo/mix_1.ll2
-rw-r--r--test/Analysis/RegionInfo/nested_loops.ll2
-rw-r--r--test/Analysis/RegionInfo/next.ll2
-rw-r--r--test/Analysis/RegionInfo/paper.ll2
-rw-r--r--test/Analysis/RegionInfo/two_loops_same_header.ll2
-rw-r--r--test/Analysis/RegionInfo/unreachable_bb.ll1
-rw-r--r--test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll26
-rw-r--r--test/Analysis/ScalarEvolution/expander-replace-congruent-ivs.ll111
-rw-r--r--test/Analysis/ScalarEvolution/flags-from-poison-dbg.ll75
-rw-r--r--test/Analysis/ScalarEvolution/flags-from-poison.ll104
-rw-r--r--test/Analysis/ScalarEvolution/guards.ll141
-rw-r--r--test/Analysis/ScalarEvolution/incorrect-offset-scaling.ll48
-rw-r--r--test/Analysis/ScalarEvolution/increasing-or-decreasing-iv.ll247
-rw-r--r--test/Analysis/ScalarEvolution/infer-prestart-no-wrap.ll12
-rw-r--r--test/Analysis/ScalarEvolution/no-wrap-unknown-becount.ll124
-rw-r--r--test/Analysis/ScalarEvolution/nowrap-preinc-limits.ll3
-rw-r--r--test/Analysis/ScalarEvolution/nsw-offset-assume.ll4
-rw-r--r--test/Analysis/ScalarEvolution/nsw-offset.ll4
-rw-r--r--test/Analysis/ScalarEvolution/nsw.ll103
-rw-r--r--test/Analysis/ScalarEvolution/overflow-intrinsics.ll309
-rw-r--r--test/Analysis/ScalarEvolution/pr27315.ll31
-rw-r--r--test/Analysis/ScalarEvolution/predicated-trip-count.ll109
-rw-r--r--test/Analysis/ScalarEvolution/returned.ll16
-rw-r--r--test/Analysis/ScalarEvolution/scev-aa.ll2
-rw-r--r--test/Analysis/ScalarEvolution/scev-canonical-mode.ll32
-rw-r--r--test/Analysis/ScalarEvolution/scev-dispositions.ll73
-rw-r--r--test/Analysis/ScalarEvolution/scev-expander-existing-value.ll38
-rw-r--r--test/Analysis/ScalarEvolution/sext-to-zext.ll23
-rw-r--r--test/Analysis/ScalarEvolution/trip-count.ll22
-rw-r--r--test/Analysis/ScalarEvolution/trip-count13.ll81
-rw-r--r--test/Analysis/ScopedNoAliasAA/basic.ll7
-rw-r--r--test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll7
-rw-r--r--test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll1
-rw-r--r--test/Analysis/ValueTracking/deref-bitcast-of-gep.ll82
-rw-r--r--test/Analysis/ValueTracking/dom-cond.ll18
-rw-r--r--test/Analysis/ValueTracking/known-bits-from-range-md.ll10
-rw-r--r--test/Analysis/ValueTracking/memory-dereferenceable.ll13
-rw-r--r--test/Analysis/ValueTracking/pr24866.ll44
-rw-r--r--test/Analysis/alias-analysis-uses.ll10
188 files changed, 6946 insertions, 664 deletions
diff --git a/test/Analysis/BasicAA/cs-cs.ll b/test/Analysis/BasicAA/cs-cs.ll
index dc298f1668bed..3bc4d72eab355 100644
--- a/test/Analysis/BasicAA/cs-cs.ll
+++ b/test/Analysis/BasicAA/cs-cs.ll
@@ -9,6 +9,7 @@ declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
declare void @a_readonly_func(i8 *) noinline nounwind readonly
+declare void @a_writeonly_func(i8 *) noinline nounwind writeonly
define <8 x i16> @test1(i8* %p, <8 x i16> %y) {
entry:
@@ -22,18 +23,18 @@ entry:
; CHECK-LABEL: Function: test1:
; CHECK: NoAlias: i8* %p, i8* %q
-; CHECK: Just Ref: Ptr: i8* %p <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
-; CHECK: NoModRef: Ptr: i8* %q <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
+; CHECK: Just Ref: Ptr: i8* %p <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
+; CHECK: NoModRef: Ptr: i8* %q <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
; CHECK: NoModRef: Ptr: i8* %p <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
; CHECK: Both ModRef: Ptr: i8* %q <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
-; CHECK: Just Ref: Ptr: i8* %p <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
-; CHECK: NoModRef: Ptr: i8* %q <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
-; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
-; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
-; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
-; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
-; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4
-; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #4 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
+; CHECK: Just Ref: Ptr: i8* %p <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
+; CHECK: NoModRef: Ptr: i8* %q <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
+; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
+; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
+; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
+; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
+; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
+; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
}
define void @test2(i8* %P, i8* %Q) nounwind ssp {
@@ -233,9 +234,23 @@ define void @test6(i8* %P) nounwind ssp {
; CHECK: Just Ref: call void @a_readonly_func(i8* %P) <-> call void @llvm.memset.p0i8.i64(i8* %P, i8 -51, i64 32, i32 8, i1 false)
}
-attributes #0 = { nounwind readonly argmemonly }
-attributes #1 = { nounwind argmemonly }
+define void @test7(i8* %P) nounwind ssp {
+ call void @a_writeonly_func(i8* %P)
+ call void @a_readonly_func(i8* %P)
+ ret void
+
+; CHECK-LABEL: Function: test7:
+
+; CHECK: Just Mod: Ptr: i8* %P <-> call void @a_writeonly_func(i8* %P)
+; CHECK: Just Ref: Ptr: i8* %P <-> call void @a_readonly_func(i8* %P)
+; CHECK: Just Mod: call void @a_writeonly_func(i8* %P) <-> call void @a_readonly_func(i8* %P)
+; CHECK: Just Ref: call void @a_readonly_func(i8* %P) <-> call void @a_writeonly_func(i8* %P)
+}
+
+attributes #0 = { argmemonly nounwind readonly }
+attributes #1 = { argmemonly nounwind }
attributes #2 = { noinline nounwind readonly }
-attributes #3 = { nounwind ssp }
-attributes #4 = { nounwind }
+attributes #3 = { noinline nounwind writeonly }
+attributes #4 = { nounwind ssp }
+attributes #5 = { nounwind }
diff --git a/test/Analysis/BasicAA/guards.ll b/test/Analysis/BasicAA/guards.ll
new file mode 100644
index 0000000000000..66cfb156b7d91
--- /dev/null
+++ b/test/Analysis/BasicAA/guards.ll
@@ -0,0 +1,30 @@
+; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
+
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) #0
+declare void @llvm.experimental.guard(i1, ...)
+declare void @unknown_but_readonly() readonly
+
+define void @test1(i8* %P, i8* %Q) {
+ tail call void(i1,...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
+ tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
+ ret void
+
+; CHECK-LABEL: Function: test1:
+
+; CHECK: Just Ref: Ptr: i8* %P <-> tail call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
+; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
+; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
+; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
+; CHECK: Just Ref: tail call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ] <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
+; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
+}
+
+define void @test2() {
+ tail call void(i1,...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
+ tail call void @unknown_but_readonly()
+ ret void
+; CHECK-LABEL: Function: test2:
+; CHECK: NoModRef: tail call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ] <-> tail call void @unknown_but_readonly()
+; CHECK: NoModRef: tail call void @unknown_but_readonly() <-> tail call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
+}
diff --git a/test/Analysis/BasicAA/negoffset.ll b/test/Analysis/BasicAA/negoffset.ll
new file mode 100644
index 0000000000000..e8550948dc1e6
--- /dev/null
+++ b/test/Analysis/BasicAA/negoffset.ll
@@ -0,0 +1,98 @@
+; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
+target triple = "i386-unknown-linux-gnu"
+
+declare i32* @random.i32(i32* %ptr)
+
+; CHECK-LABEL: Function: arr:
+; CHECK-DAG: MayAlias: i32* %alloca, i32* %p0
+; CHECK-DAG: NoAlias: i32* %alloca, i32* %p1
+define void @arr() {
+ %alloca = alloca i32, i32 4
+ %random = call i32* @random.i32(i32* %alloca)
+ %p0 = getelementptr inbounds i32, i32* %random, i32 0
+ %p1 = getelementptr inbounds i32, i32* %random, i32 1
+ ret void
+}
+
+; CHECK-LABEL: Function: arg:
+; CHECK-DAG: MayAlias: i32* %arg, i32* %p0
+; CHECK-DAG: MayAlias: i32* %arg, i32* %p1
+define void @arg(i32* %arg) {
+ %random = call i32* @random.i32(i32* %arg)
+ %p0 = getelementptr inbounds i32, i32* %random, i32 0
+ %p1 = getelementptr inbounds i32, i32* %random, i32 1
+ ret void
+}
+
+@gv = global i32 1
+; CHECK-LABEL: Function: global:
+; CHECK-DAG: MayAlias: i32* %p0, i32* @gv
+; CHECK-DAG: NoAlias: i32* %p1, i32* @gv
+define void @global() {
+ %random = call i32* @random.i32(i32* @gv)
+ %p0 = getelementptr inbounds i32, i32* %random, i32 0
+ %p1 = getelementptr inbounds i32, i32* %random, i32 1
+ ret void
+}
+
+; CHECK-LABEL: Function: struct:
+; CHECK-DAG: MayAlias: i32* %f0, i32* %p0
+; CHECK-DAG: MayAlias: i32* %f1, i32* %p0
+; CHECK-DAG: NoAlias: i32* %f0, i32* %p1
+; CHECK-DAG: MayAlias: i32* %f1, i32* %p1
+%struct = type { i32, i32, i32 }
+define void @struct() {
+ %alloca = alloca %struct
+ %alloca.i32 = bitcast %struct* %alloca to i32*
+ %random = call i32* @random.i32(i32* %alloca.i32)
+ %f0 = getelementptr inbounds %struct, %struct* %alloca, i32 0, i32 0
+ %f1 = getelementptr inbounds %struct, %struct* %alloca, i32 0, i32 1
+ %p0 = getelementptr inbounds i32, i32* %random, i32 0
+ %p1 = getelementptr inbounds i32, i32* %random, i32 1
+ ret void
+}
+
+; CHECK-LABEL: Function: complex1:
+; CHECK-DAG: MayAlias: i32* %a2.0, i32* %r2.0
+; CHECK-DAG: NoAlias: i32* %a2.0, i32* %r2.1
+; CHECK-DAG: MayAlias: i32* %a2.0, i32* %r2.i
+; CHECK-DAG: MayAlias: i32* %a2.0, i32* %r2.1i
+; CHECK-DAG: NoAlias: i32* %a1, i32* %r2.0
+; CHECK-DAG: NoAlias: i32* %a1, i32* %r2.1
+; CHECK-DAG: NoAlias: i32* %a1, i32* %r2.i
+; CHECK-DAG: NoAlias: i32* %a1, i32* %r2.1i
+%complex = type { i32, i32, [4 x i32] }
+define void @complex1(i32 %i) {
+ %alloca = alloca %complex
+ %alloca.i32 = bitcast %complex* %alloca to i32*
+ %r.i32 = call i32* @random.i32(i32* %alloca.i32)
+ %random = bitcast i32* %r.i32 to %complex*
+ %a1 = getelementptr inbounds %complex, %complex* %alloca, i32 0, i32 1
+ %a2.0 = getelementptr inbounds %complex, %complex* %alloca, i32 0, i32 2, i32 0
+ %r2.0 = getelementptr inbounds %complex, %complex* %random, i32 0, i32 2, i32 0
+ %r2.1 = getelementptr inbounds %complex, %complex* %random, i32 0, i32 2, i32 1
+ %r2.i = getelementptr inbounds %complex, %complex* %random, i32 0, i32 2, i32 %i
+ %r2.1i = getelementptr inbounds i32, i32* %r2.1, i32 %i
+ ret void
+}
+
+; CHECK-LABEL: Function: complex2:
+; CHECK-DAG: NoAlias: i32* %alloca, i32* %p120
+; CHECK-DAG: NoAlias: i32* %alloca, i32* %pi20
+; CHECK-DAG: NoAlias: i32* %alloca, i32* %pij1
+; CHECK-DAG: MayAlias: i32* %a3, i32* %pij1
+%inner = type { i32, i32 }
+%outer = type { i32, i32, [10 x %inner] }
+declare %outer* @rand_outer(i32* %p)
+define void @complex2(i32 %i, i32 %j) {
+ %alloca = alloca i32, i32 128
+ %a3 = getelementptr inbounds i32, i32* %alloca, i32 3
+ %random = call %outer* @rand_outer(i32* %alloca)
+ %p120 = getelementptr inbounds %outer, %outer* %random, i32 1, i32 2, i32 2, i32 0
+ %pi20 = getelementptr inbounds %outer, %outer* %random, i32 %i, i32 2, i32 2, i32 0
+ %pij1 = getelementptr inbounds %outer, %outer* %random, i32 %i, i32 2, i32 %j, i32 1
+ ret void
+}
+
diff --git a/test/Analysis/BasicAA/noalias-wraparound-bug.ll b/test/Analysis/BasicAA/noalias-wraparound-bug.ll
new file mode 100644
index 0000000000000..a75322ed3e9d4
--- /dev/null
+++ b/test/Analysis/BasicAA/noalias-wraparound-bug.ll
@@ -0,0 +1,24 @@
+; RUN: opt -S -basicaa -gvn < %s | FileCheck %s
+
+target datalayout = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128"
+target triple = "i386-apple-macosx10.6.0"
+
+; We incorrectly returned noalias in the example below for "tmp5" and
+; "tmp12" returning i32 32, since basicaa converted the offsets to 64b
+; and missed the wrap-around
+
+define i32 @foo(i8* %buffer) {
+entry:
+ %tmp2 = getelementptr i8, i8* %buffer, i32 -2071408432
+ %tmp3 = bitcast i8* %tmp2 to i32*
+ %tmp4 = getelementptr i8, i8* %buffer, i32 128
+ %tmp5 = bitcast i8* %tmp4 to i32*
+ store i32 32, i32* %tmp5, align 4
+ %tmp12 = getelementptr i32, i32* %tmp3, i32 -1629631508
+ store i32 28, i32* %tmp12, align 4
+ %tmp13 = getelementptr i8, i8* %buffer, i32 128
+ %tmp14 = bitcast i8* %tmp13 to i32*
+ %tmp2083 = load i32, i32* %tmp14, align 4
+; CHECK: ret i32 28
+ ret i32 %tmp2083
+}
diff --git a/test/Analysis/BasicAA/phi-aa.ll b/test/Analysis/BasicAA/phi-aa.ll
index 3944e9e435666..e410520bc0fce 100644
--- a/test/Analysis/BasicAA/phi-aa.ll
+++ b/test/Analysis/BasicAA/phi-aa.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/Analysis/BasicAA/returned.ll b/test/Analysis/BasicAA/returned.ll
new file mode 100644
index 0000000000000..c6ef6806140df
--- /dev/null
+++ b/test/Analysis/BasicAA/returned.ll
@@ -0,0 +1,45 @@
+; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+%struct = type { i32, i32, i32 }
+
+; CHECK-LABEL: test_simple
+
+; CHECK-DAG: MustAlias: %struct* %st, %struct* %sta
+
+; CHECK-DAG: PartialAlias: %struct* %st, i32* %x
+; CHECK-DAG: PartialAlias: %struct* %st, i32* %y
+; CHECK-DAG: PartialAlias: %struct* %st, i32* %z
+
+; CHECK-DAG: NoAlias: i32* %x, i32* %y
+; CHECK-DAG: NoAlias: i32* %x, i32* %z
+; CHECK-DAG: NoAlias: i32* %y, i32* %z
+
+; CHECK-DAG: PartialAlias: %struct* %st, %struct* %y_12
+; CHECK-DAG: PartialAlias: %struct* %y_12, i32* %x
+; CHECK-DAG: PartialAlias: i32* %x, i80* %y_10
+
+; CHECK-DAG: PartialAlias: %struct* %st, i64* %y_8
+; CHECK-DAG: PartialAlias: i32* %z, i64* %y_8
+; CHECK-DAG: NoAlias: i32* %x, i64* %y_8
+
+; CHECK-DAG: MustAlias: %struct* %y_12, i32* %y
+; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
+; CHECK-DAG: MustAlias: i32* %y, i80* %y_10
+
+define void @test_simple(%struct* %st, i64 %i, i64 %j, i64 %k) {
+ %x = getelementptr %struct, %struct* %st, i64 %i, i32 0
+ %y = getelementptr %struct, %struct* %st, i64 %j, i32 1
+ %sta = call %struct* @func2(%struct* %st)
+ %z = getelementptr %struct, %struct* %sta, i64 %k, i32 2
+ %y_12 = bitcast i32* %y to %struct*
+ %y_10 = bitcast i32* %y to i80*
+ %ya = call i32* @func1(i32* %y)
+ %y_8 = bitcast i32* %ya to i64*
+ ret void
+}
+
+declare i32* @func1(i32* returned) nounwind
+declare %struct* @func2(%struct* returned) nounwind
+
diff --git a/test/Analysis/BasicAA/struct-geps.ll b/test/Analysis/BasicAA/struct-geps.ll
index d63c71a3278b9..2d85e1dd0173d 100644
--- a/test/Analysis/BasicAA/struct-geps.ll
+++ b/test/Analysis/BasicAA/struct-geps.ll
@@ -162,3 +162,12 @@ define void @test_struct_in_array(%struct2* %st, i64 %i, i64 %j, i64 %k) {
%y = getelementptr %struct2, %struct2* %st, i32 0, i32 0, i32 1, i32 1
ret void
}
+
+; PR27418 - Treat GEP indices with the same value but different types the same
+; CHECK-LABEL: test_different_index_types
+; CHECK: MustAlias: i16* %tmp1, i16* %tmp2
+define void @test_different_index_types([2 x i16]* %arr) {
+ %tmp1 = getelementptr [2 x i16], [2 x i16]* %arr, i16 0, i32 1
+ %tmp2 = getelementptr [2 x i16], [2 x i16]* %arr, i16 0, i16 1
+ ret void
+}
diff --git a/test/Analysis/BlockFrequencyInfo/bad_input.ll b/test/Analysis/BlockFrequencyInfo/bad_input.ll
index 20b87e6dfcb40..39009a5ba838f 100644
--- a/test/Analysis/BlockFrequencyInfo/bad_input.ll
+++ b/test/Analysis/BlockFrequencyInfo/bad_input.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -analyze -block-freq | FileCheck %s
+; RUN: opt < %s -passes='print<block-freq>' -disable-output 2>&1 | FileCheck %s
declare void @g(i32 %x)
diff --git a/test/Analysis/BlockFrequencyInfo/basic.ll b/test/Analysis/BlockFrequencyInfo/basic.ll
index 8e81cc2ea31cc..a957adc65027e 100644
--- a/test/Analysis/BlockFrequencyInfo/basic.ll
+++ b/test/Analysis/BlockFrequencyInfo/basic.ll
@@ -1,4 +1,6 @@
; RUN: opt < %s -analyze -block-freq | FileCheck %s
+; RUN: opt < %s -analyze -lazy-block-freq | FileCheck %s
+; RUN: opt < %s -passes='print<block-freq>' -disable-output 2>&1 | FileCheck %s
define i32 @test1(i32 %i, i32* %a) {
; CHECK-LABEL: Printing analysis {{.*}} for function 'test1':
diff --git a/test/Analysis/BlockFrequencyInfo/double_backedge.ll b/test/Analysis/BlockFrequencyInfo/double_backedge.ll
index 597bf8329b263..4431c3a68219e 100644
--- a/test/Analysis/BlockFrequencyInfo/double_backedge.ll
+++ b/test/Analysis/BlockFrequencyInfo/double_backedge.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -analyze -block-freq | FileCheck %s
+; RUN: opt < %s -passes='print<block-freq>' -disable-output 2>&1 | FileCheck %s
define void @double_backedge(i1 %x) {
; CHECK-LABEL: Printing analysis {{.*}} for function 'double_backedge':
diff --git a/test/Analysis/BlockFrequencyInfo/double_exit.ll b/test/Analysis/BlockFrequencyInfo/double_exit.ll
index 3063ba7017310..5e9dded162c41 100644
--- a/test/Analysis/BlockFrequencyInfo/double_exit.ll
+++ b/test/Analysis/BlockFrequencyInfo/double_exit.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -analyze -block-freq | FileCheck %s
+; RUN: opt < %s -passes='print<block-freq>' -disable-output 2>&1 | FileCheck %s
; CHECK-LABEL: Printing analysis {{.*}} for function 'double_exit':
; CHECK-NEXT: block-frequency-info: double_exit
diff --git a/test/Analysis/BlockFrequencyInfo/extremely-likely-loop-successor.ll b/test/Analysis/BlockFrequencyInfo/extremely-likely-loop-successor.ll
index e55deaff428df..b9623683fe5a8 100644
--- a/test/Analysis/BlockFrequencyInfo/extremely-likely-loop-successor.ll
+++ b/test/Analysis/BlockFrequencyInfo/extremely-likely-loop-successor.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -analyze -block-freq | FileCheck %s
+; RUN: opt < %s -passes='print<block-freq>' -disable-output 2>&1 | FileCheck %s
; PR21622: Check for a crasher when the sum of exits to the same successor of a
; loop overflows.
diff --git a/test/Analysis/BlockFrequencyInfo/irreducible.ll b/test/Analysis/BlockFrequencyInfo/irreducible.ll
index c1b1c2a7a23c1..83b0056636cfd 100644
--- a/test/Analysis/BlockFrequencyInfo/irreducible.ll
+++ b/test/Analysis/BlockFrequencyInfo/irreducible.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -analyze -block-freq | FileCheck %s
+; RUN: opt < %s -passes='print<block-freq>' -disable-output 2>&1 | FileCheck %s
; A loop with multiple exits isn't irreducible. It should be handled
; correctly.
diff --git a/test/Analysis/BlockFrequencyInfo/irreducible_loop_crash.ll b/test/Analysis/BlockFrequencyInfo/irreducible_loop_crash.ll
index 2bcd088dd16ed..8cd334f04bca1 100644
--- a/test/Analysis/BlockFrequencyInfo/irreducible_loop_crash.ll
+++ b/test/Analysis/BlockFrequencyInfo/irreducible_loop_crash.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -analyze -block-freq
+; RUN: opt < %s -passes='print<block-freq>' -disable-output
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/Analysis/BlockFrequencyInfo/loop_with_branch.ll b/test/Analysis/BlockFrequencyInfo/loop_with_branch.ll
index 9a86564c548dd..40d9e82351fd1 100644
--- a/test/Analysis/BlockFrequencyInfo/loop_with_branch.ll
+++ b/test/Analysis/BlockFrequencyInfo/loop_with_branch.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -analyze -block-freq | FileCheck %s
+; RUN: opt < %s -passes='print<block-freq>' -disable-output 2>&1 | FileCheck %s
; CHECK-LABEL: Printing analysis {{.*}} for function 'loop_with_branch':
; CHECK-NEXT: block-frequency-info: loop_with_branch
diff --git a/test/Analysis/BlockFrequencyInfo/loops_with_profile_info.ll b/test/Analysis/BlockFrequencyInfo/loops_with_profile_info.ll
index 29a9f3b29fb08..3133e167de5fb 100644
--- a/test/Analysis/BlockFrequencyInfo/loops_with_profile_info.ll
+++ b/test/Analysis/BlockFrequencyInfo/loops_with_profile_info.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -analyze -block-freq | FileCheck %s
+; RUN: opt < %s -passes='print<block-freq>' -disable-output 2>&1 | FileCheck %s
; This code contains three loops. One is triple-nested, the
; second is double nested and the third is a single loop. At
diff --git a/test/Analysis/BlockFrequencyInfo/nested_loop_with_branches.ll b/test/Analysis/BlockFrequencyInfo/nested_loop_with_branches.ll
index 19d165805b046..7025b5d16a450 100644
--- a/test/Analysis/BlockFrequencyInfo/nested_loop_with_branches.ll
+++ b/test/Analysis/BlockFrequencyInfo/nested_loop_with_branches.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -analyze -block-freq | FileCheck %s
+; RUN: opt < %s -passes='print<block-freq>' -disable-output 2>&1 | FileCheck %s
; CHECK-LABEL: Printing analysis {{.*}} for function 'nested_loop_with_branches'
; CHECK-NEXT: block-frequency-info: nested_loop_with_branches
diff --git a/test/Analysis/BranchProbabilityInfo/basic.ll b/test/Analysis/BranchProbabilityInfo/basic.ll
index d833b8339aac4..d86709130f34c 100644
--- a/test/Analysis/BranchProbabilityInfo/basic.ll
+++ b/test/Analysis/BranchProbabilityInfo/basic.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -analyze -branch-prob | FileCheck %s
+; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s
define i32 @test1(i32 %i, i32* %a) {
; CHECK: Printing analysis {{.*}} for function 'test1'
diff --git a/test/Analysis/BranchProbabilityInfo/deopt-intrinsic.ll b/test/Analysis/BranchProbabilityInfo/deopt-intrinsic.ll
new file mode 100644
index 0000000000000..faa09f9e8a0c4
--- /dev/null
+++ b/test/Analysis/BranchProbabilityInfo/deopt-intrinsic.ll
@@ -0,0 +1,21 @@
+; RUN: opt -analyze -branch-prob < %s | FileCheck %s
+; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s
+
+declare i32 @llvm.experimental.deoptimize.i32(...)
+
+define i32 @test1(i32 %a, i32 %b) {
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test1':
+entry:
+ %cond = icmp eq i32 %a, 42
+ br i1 %cond, label %exit, label %deopt
+
+; CHECK: edge entry -> exit probability is 0x7ffff800 / 0x80000000 = 100.00% [HOT edge]
+; CHECK: edge entry -> deopt probability is 0x00000800 / 0x80000000 = 0.00%
+
+deopt:
+ %rval = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
+ ret i32 %rval
+
+exit:
+ ret i32 %b
+}
diff --git a/test/Analysis/BranchProbabilityInfo/loop.ll b/test/Analysis/BranchProbabilityInfo/loop.ll
index 5be7adf3909df..1a37a7a4659ef 100644
--- a/test/Analysis/BranchProbabilityInfo/loop.ll
+++ b/test/Analysis/BranchProbabilityInfo/loop.ll
@@ -1,5 +1,6 @@
; Test the static branch probability heuristics for no-return functions.
; RUN: opt < %s -analyze -branch-prob | FileCheck %s
+; RUN: opt < %s -passes='print<branch-prob>' --disable-output 2>&1 | FileCheck %s
declare void @g1()
declare void @g2()
diff --git a/test/Analysis/BranchProbabilityInfo/noreturn.ll b/test/Analysis/BranchProbabilityInfo/noreturn.ll
index 7098c2f7b8ccf..0c2fe863d034d 100644
--- a/test/Analysis/BranchProbabilityInfo/noreturn.ll
+++ b/test/Analysis/BranchProbabilityInfo/noreturn.ll
@@ -1,5 +1,6 @@
; Test the static branch probability heuristics for no-return functions.
; RUN: opt < %s -analyze -branch-prob | FileCheck %s
+; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s
declare void @abort() noreturn
diff --git a/test/Analysis/BranchProbabilityInfo/pr18705.ll b/test/Analysis/BranchProbabilityInfo/pr18705.ll
index f5f9612fcdb67..74983ef1b4f01 100644
--- a/test/Analysis/BranchProbabilityInfo/pr18705.ll
+++ b/test/Analysis/BranchProbabilityInfo/pr18705.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -analyze -branch-prob | FileCheck %s
+; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s
; Since neither of while.body's out-edges is an exit or a back edge,
; calcLoopBranchHeuristics should return early without setting the weights.
diff --git a/test/Analysis/BranchProbabilityInfo/pr22718.ll b/test/Analysis/BranchProbabilityInfo/pr22718.ll
index 51bbd13e83c16..66ac89793b877 100644
--- a/test/Analysis/BranchProbabilityInfo/pr22718.ll
+++ b/test/Analysis/BranchProbabilityInfo/pr22718.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -analyze -branch-prob | FileCheck %s
+; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s
; In this test, the else clause is taken about 90% of the time. This was not
; reflected in the probability computation because the weight is larger than
diff --git a/test/Analysis/CFLAliasAnalysis/Andersen/assign.ll b/test/Analysis/CFLAliasAnalysis/Andersen/assign.ll
new file mode 100644
index 0000000000000..237fe72732e8d
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Andersen/assign.ll
@@ -0,0 +1,24 @@
+; This testcase ensures that CFL AA handles assignment in an inclusion-based
+; manner
+
+; RUN: opt < %s -disable-basicaa -cfl-anders-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-anders-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+; CHECK-LABEL: Function: test_assign
+; CHECK: NoAlias: i64* %a, i64* %b
+; CHECK: NoAlias: i32* %c, i64* %b
+; CHECK: NoAlias: i32* %d, i64* %a
+; CHECK: NoAlias: i32* %c, i32* %d
+; CHECK: MayAlias: i32* %e, i64* %a
+; CHECK: MayAlias: i32* %e, i64* %b
+; CHECK: MayAlias: i32* %c, i32* %e
+; CHECK: MayAlias: i32* %d, i32* %e
+define void @test_assign(i1 %cond) {
+ %a = alloca i64, align 8
+ %b = alloca i64, align 8
+
+ %c = bitcast i64* %a to i32*
+ %d = bitcast i64* %b to i32*
+ %e = select i1 %cond, i32* %c, i32* %d
+ ret void
+} \ No newline at end of file
diff --git a/test/Analysis/CFLAliasAnalysis/Andersen/assign2.ll b/test/Analysis/CFLAliasAnalysis/Andersen/assign2.ll
new file mode 100644
index 0000000000000..8bd98f388f05e
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Andersen/assign2.ll
@@ -0,0 +1,23 @@
+; This testcase ensures that CFL AA handles assignment in an inclusion-based
+; manner
+
+; RUN: opt < %s -disable-basicaa -cfl-anders-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-anders-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+; CHECK-LABEL: Function: test_assign2
+; CHECK: NoAlias: i32* %b, i64* %a
+; CHECK: NoAlias: i32* %b, i32* %c
+; CHECK: NoAlias: i32* %b, i32* %d
+; CHECK: MayAlias: i32* %e, i64* %a
+; CHECK: MayAlias: i32* %b, i32* %e
+; CHECK: MayAlias: i32* %c, i32* %e
+; CHECK: MayAlias: i32* %d, i32* %e
+define void @test_assign2(i1 %cond) {
+ %a = alloca i64, align 8
+ %b = alloca i32, align 4
+
+ %c = bitcast i64* %a to i32*
+ %d = bitcast i64* %a to i32*
+ %e = select i1 %cond, i32* %c, i32* %b
+ ret void
+} \ No newline at end of file
diff --git a/test/Analysis/CFLAliasAnalysis/Andersen/attrs-below.ll b/test/Analysis/CFLAliasAnalysis/Andersen/attrs-below.ll
new file mode 100644
index 0000000000000..4cf918081bb50
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Andersen/attrs-below.ll
@@ -0,0 +1,61 @@
+; This testcase ensures that AliasAttrs are propagated not only on the same
+; level but also downward.
+
+; RUN: opt < %s -disable-basicaa -cfl-anders-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-anders-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+; CHECK-LABEL: Function: test_attr_below
+; CHECK: MayAlias: i64* %q, i64*** %p
+; CHECK: NoAlias: i64* %esc, i64*** %p
+; CHECK: NoAlias: i64* %esc, i64* %q
+
+; CHECK: MayAlias: i64* %unknown, i64*** %p
+; CHECK: MayAlias: i64* %q, i64* %unknown
+; CHECK: MayAlias: i64* %esc, i64* %unknown
+; CHECK: MayAlias: i64* %q, i64** %pdrf
+; CHECK: MayAlias: i64* %esc, i64** %pdrf
+; CHECK: MayAlias: i64* %unknown, i64** %pdrf
+; CHECK: MayAlias: i64* %pdrf2, i64* %q
+; CHECK: MayAlias: i64* %esc, i64* %pdrf2
+; CHECK: MayAlias: i64* %pdrf2, i64* %unknown
+define void @test_attr_below(i64*** %p, i64* %q) {
+ %esc = alloca i64, align 8
+ %escint = ptrtoint i64* %esc to i64
+ %unknown = inttoptr i64 %escint to i64*
+
+ %pdrf = load i64**, i64*** %p
+ %pdrf2 = load i64*, i64** %pdrf
+
+ ret void
+}
+
+; CHECK-LABEL: Function: test_attr_assign_below
+; CHECK: MayAlias: i64** %sel, i64*** %p
+; CHECK: MayAlias: i64* %q, i64** %sel
+; CHECK: MayAlias: i64** %a, i64** %sel
+; CHECK: MayAlias: i64** %pdrf, i64** %sel
+
+; CHECK: MayAlias: i64** %c, i64*** %p
+; CHECK: MayAlias: i64* %q, i64** %c
+; CHECK: MayAlias: i64** %a, i64** %c
+; CHECK: MayAlias: i64** %c, i64** %pdrf
+; CHECK: MayAlias: i64** %c, i64** %sel
+
+; CHECK: MayAlias: i64* %d, i64*** %p
+; CHECK: MayAlias: i64* %d, i64* %q
+; CHECK: MayAlias: i64* %d, i64** %pdrf
+; CHECK: MayAlias: i64* %d, i64** %sel
+define void @test_attr_assign_below(i64*** %p, i64* %q, i1 %cond) {
+ %a = alloca i64*, align 8
+ %pdrf = load i64**, i64*** %p
+ %sel = select i1 %cond, i64** %a, i64** %pdrf
+
+ %b = alloca i64**, align 8
+ store i64** %sel, i64*** %b
+
+ %c = load i64**, i64*** %b
+ %d = load i64*, i64** %c
+
+ ret void
+}
+
diff --git a/test/Analysis/CFLAliasAnalysis/Andersen/attrs.ll b/test/Analysis/CFLAliasAnalysis/Andersen/attrs.ll
new file mode 100644
index 0000000000000..4ba3d1510be9e
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Andersen/attrs.ll
@@ -0,0 +1,94 @@
+; This testcase ensures that CFL AA handles escaped values no more conservative than it should
+
+; RUN: opt < %s -disable-basicaa -cfl-anders-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-anders-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+; CHECK-LABEL: Function: test_local
+; CHECK: NoAlias: i32* %a, i32* %b
+; CHECK: MayAlias: i32* %a, i32* %aAlias
+; CHECK: NoAlias: i32* %aAlias, i32* %b
+define void @test_local() {
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+ %aint = ptrtoint i32* %a to i64
+ %aAlias = inttoptr i64 %aint to i32*
+ ret void
+}
+
+; CHECK-LABEL: Function: test_global_param
+; CHECK: NoAlias: i32* %a, i32** %x
+; CHECK: MayAlias: i32* %a, i32* %xload
+; CHECK: MayAlias: i32* %a, i32* %gload
+; CHECK: MayAlias: i32* %gload, i32* %xload
+; CHECK: MayAlias: i32** %x, i32** @ext_global
+; CHECK: NoAlias: i32* %a, i32** @ext_global
+@ext_global = external global i32*
+define void @test_global_param(i32** %x) {
+ %a = alloca i32, align 4
+ %aint = ptrtoint i32* %a to i64
+ %xload = load i32*, i32** %x
+ %gload = load i32*, i32** @ext_global
+ ret void
+}
+
+declare void @external_func(i32**)
+; CHECK-LABEL: Function: test_external_call
+; CHECK: NoAlias: i32* %b, i32* %x
+; CHECK: NoAlias: i32* %b, i32** %a
+; CHECK: MayAlias: i32* %c, i32* %x
+; CHECK: MayAlias: i32* %c, i32** %a
+; CHECK: NoAlias: i32* %b, i32* %c
+define void @test_external_call(i32* %x) {
+ %a = alloca i32*, align 8
+ %b = alloca i32, align 4
+ call void @external_func(i32** %a)
+ %c = load i32*, i32** %a
+ ret void
+}
+
+declare void @external_func_readonly(i32**) readonly
+; CHECK-LABEL: Function: test_external_call_func_readonly
+; CHECK: MayAlias: i32* %c, i32* %x
+; CHECK: NoAlias: i32* %c, i32** %a
+define void @test_external_call_func_readonly(i32* %x) {
+ %a = alloca i32*, align 8
+ %b = alloca i32, align 4
+ store i32* %x, i32** %a, align 4
+ call void @external_func_readonly(i32** %a)
+ %c = load i32*, i32** %a
+ ret void
+}
+
+; CHECK-LABEL: Function: test_external_call_callsite_readonly
+; CHECK: MayAlias: i32* %c, i32* %x
+; CHECK: NoAlias: i32* %c, i32** %a
+define void @test_external_call_callsite_readonly(i32* %x) {
+ %a = alloca i32*, align 8
+ %b = alloca i32, align 4
+ store i32* %x, i32** %a, align 4
+ call void @external_func(i32** %a) readonly
+ %c = load i32*, i32** %a
+ ret void
+}
+
+declare i32* @external_func_normal_return(i32*)
+; CHECK-LABEL: Function: test_external_call_normal_return
+; CHECK: MayAlias: i32* %c, i32* %x
+; CHECK: MayAlias: i32* %a, i32* %c
+define void @test_external_call_normal_return(i32* %x) {
+ %a = alloca i32, align 8
+ %b = alloca i32, align 4
+ %c = call i32* @external_func_normal_return(i32* %a)
+ ret void
+}
+
+declare noalias i32* @external_func_noalias_return(i32*)
+; CHECK-LABEL: Function: test_external_call_noalias_return
+; CHECK: NoAlias: i32* %c, i32* %x
+; CHECK: NoAlias: i32* %a, i32* %c
+define void @test_external_call_noalias_return(i32* %x) {
+ %a = alloca i32, align 8
+ %b = alloca i32, align 4
+ %c = call i32* @external_func_noalias_return(i32* %a)
+ ret void
+}
diff --git a/test/Analysis/CFLAliasAnalysis/Andersen/cycle.ll b/test/Analysis/CFLAliasAnalysis/Andersen/cycle.ll
new file mode 100644
index 0000000000000..4ce9467ddc374
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Andersen/cycle.ll
@@ -0,0 +1,34 @@
+; This testcase ensures that CFL AA handles assignment cycles correctly
+
+; RUN: opt < %s -disable-basicaa -cfl-anders-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-anders-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+; CHECK-LABEL: Function: test_cycle
+; CHECK: NoAlias: i64* %a, i64** %b
+; CHECK: NoAlias: i64* %a, i64*** %c
+; CHECK: NoAlias: i64** %b, i64*** %c
+; CHECK: NoAlias: i64* %a, i64**** %d
+; CHECK: NoAlias: i64** %b, i64**** %d
+; CHECK: NoAlias: i64*** %c, i64**** %d
+; CHECK: NoAlias: i64* %a, i64* %e
+; CHECK: NoAlias: i64* %e, i64** %b
+; CHECK: NoAlias: i64* %e, i64*** %c
+; CHECK: MayAlias: i64* %a, i64* %f
+; CHECK: NoAlias: i64* %f, i64** %b
+; CHECK: NoAlias: i64* %f, i64*** %c
+; CHECK: MayAlias: i64* %f, i64**** %d
+; CHECK: MayAlias: i64* %e, i64* %f
+define void @test_cycle() {
+ %a = alloca i64, align 8
+ %b = alloca i64*, align 8
+ %c = alloca i64**, align 8
+ %d = alloca i64***, align 8
+ store i64* %a, i64** %b
+ store i64** %b, i64*** %c
+ store i64*** %c, i64**** %d
+
+ %e = bitcast i64**** %d to i64*
+ store i64* %e, i64** %b
+ %f = load i64*, i64** %b
+ ret void
+}
diff --git a/test/Analysis/CFLAliasAnalysis/Andersen/memalias.ll b/test/Analysis/CFLAliasAnalysis/Andersen/memalias.ll
new file mode 100644
index 0000000000000..d3fb09091aa0c
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Andersen/memalias.ll
@@ -0,0 +1,21 @@
+; This testcase ensures that CFL AA correctly handles simple memory alias
+; pattern
+
+; RUN: opt < %s -disable-basicaa -cfl-anders-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-anders-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+; CHECK-LABEL: Function: test_memalias
+; CHECK: NoAlias: i64* %a, i64** %b
+; CHECK: NoAlias: i32** %c, i64* %a
+; CHECK: MayAlias: i32* %d, i64* %a
+; CHECK: NoAlias: i32* %d, i64** %b
+; CHECK: NoAlias: i32* %d, i32** %c
+define void @test_memalias() {
+ %a = alloca i64, align 8
+ %b = alloca i64*, align 8
+ store i64* %a, i64** %b
+
+ %c = bitcast i64** %b to i32**
+ %d = load i32*, i32** %c
+ ret void
+} \ No newline at end of file
diff --git a/test/Analysis/CFLAliasAnalysis/arguments-globals.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/arguments-globals.ll
index 4844577d6fef2..aa3cada3bec6d 100644
--- a/test/Analysis/CFLAliasAnalysis/arguments-globals.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/arguments-globals.ll
@@ -3,7 +3,7 @@
; (Everything should alias everything, because args can alias globals, so the
; aliasing sets should of args+alloca+global should be combined)
-; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
; CHECK: Function: test
diff --git a/test/Analysis/CFLAliasAnalysis/arguments.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/arguments.ll
index f3e6679c35e27..85f3bc64e0dcf 100644
--- a/test/Analysis/CFLAliasAnalysis/arguments.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/arguments.ll
@@ -1,7 +1,7 @@
; This testcase ensures that CFL AA gives conservative answers on variables
; that involve arguments.
-; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -cfl-steens-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
; CHECK: Function: test
diff --git a/test/Analysis/CFLAliasAnalysis/asm-global-bugfix.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/asm-global-bugfix.ll
index ec2de54e3eee1..341aafdab8645 100644
--- a/test/Analysis/CFLAliasAnalysis/asm-global-bugfix.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/asm-global-bugfix.ll
@@ -2,7 +2,7 @@
; whether two values that didn't belong to a function (i.e. two globals, etc)
; aliased.
-; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -cfl-steens-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
@G = private unnamed_addr constant [1 x i8] c"\00", align 1
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/attr-escape.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/attr-escape.ll
new file mode 100644
index 0000000000000..3adce6a923b25
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/attr-escape.ll
@@ -0,0 +1,94 @@
+; This testcase ensures that CFL AA handles escaped values no more conservative than it should
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+; CHECK-LABEL: Function: test_local
+; CHECK: NoAlias: i32* %a, i32* %b
+; CHECK: MayAlias: i32* %a, i32* %aAlias
+; CHECK: NoAlias: i32* %aAlias, i32* %b
+define void @test_local() {
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+ %aint = ptrtoint i32* %a to i64
+ %aAlias = inttoptr i64 %aint to i32*
+ ret void
+}
+
+; CHECK-LABEL: Function: test_global_param
+; CHECK: NoAlias: i32* %a, i32** %x
+; CHECK: MayAlias: i32* %a, i32* %xload
+; CHECK: MayAlias: i32* %a, i32* %gload
+; CHECK: MayAlias: i32* %gload, i32* %xload
+; CHECK: MayAlias: i32** %x, i32** @ext_global
+; CHECK: NoAlias: i32* %a, i32** @ext_global
+@ext_global = external global i32*
+define void @test_global_param(i32** %x) {
+ %a = alloca i32, align 4
+ %aint = ptrtoint i32* %a to i64
+ %xload = load i32*, i32** %x
+ %gload = load i32*, i32** @ext_global
+ ret void
+}
+
+declare void @external_func(i32**)
+; CHECK-LABEL: Function: test_external_call
+; CHECK: NoAlias: i32* %b, i32* %x
+; CHECK: NoAlias: i32* %b, i32** %a
+; CHECK: MayAlias: i32* %c, i32* %x
+; CHECK: MayAlias: i32* %c, i32** %a
+; CHECK: NoAlias: i32* %b, i32* %c
+define void @test_external_call(i32* %x) {
+ %a = alloca i32*, align 8
+ %b = alloca i32, align 4
+ call void @external_func(i32** %a)
+ %c = load i32*, i32** %a
+ ret void
+}
+
+declare void @external_func_readonly(i32**) readonly
+; CHECK-LABEL: Function: test_external_call_func_readonly
+; CHECK: MayAlias: i32* %c, i32* %x
+; CHECK: NoAlias: i32* %c, i32** %a
+define void @test_external_call_func_readonly(i32* %x) {
+ %a = alloca i32*, align 8
+ %b = alloca i32, align 4
+ store i32* %x, i32** %a, align 4
+ call void @external_func_readonly(i32** %a)
+ %c = load i32*, i32** %a
+ ret void
+}
+
+; CHECK-LABEL: Function: test_external_call_callsite_readonly
+; CHECK: MayAlias: i32* %c, i32* %x
+; CHECK: NoAlias: i32* %c, i32** %a
+define void @test_external_call_callsite_readonly(i32* %x) {
+ %a = alloca i32*, align 8
+ %b = alloca i32, align 4
+ store i32* %x, i32** %a, align 4
+ call void @external_func(i32** %a) readonly
+ %c = load i32*, i32** %a
+ ret void
+}
+
+declare i32* @external_func_normal_return(i32*)
+; CHECK-LABEL: Function: test_external_call_normal_return
+; CHECK: MayAlias: i32* %c, i32* %x
+; CHECK: MayAlias: i32* %a, i32* %c
+define void @test_external_call_normal_return(i32* %x) {
+ %a = alloca i32, align 8
+ %b = alloca i32, align 4
+ %c = call i32* @external_func_normal_return(i32* %a)
+ ret void
+}
+
+declare noalias i32* @external_func_noalias_return(i32*)
+; CHECK-LABEL: Function: test_external_call_noalias_return
+; CHECK: NoAlias: i32* %c, i32* %x
+; CHECK: NoAlias: i32* %a, i32* %c
+define void @test_external_call_noalias_return(i32* %x) {
+ %a = alloca i32, align 8
+ %b = alloca i32, align 4
+ %c = call i32* @external_func_noalias_return(i32* %a)
+ ret void
+}
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/basic-interproc.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/basic-interproc.ll
new file mode 100644
index 0000000000000..8a1d62ebd247b
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/basic-interproc.ll
@@ -0,0 +1,22 @@
+; This testcase ensures that CFL AA won't be too conservative when trying to do
+; interprocedural analysis on simple callee
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+; CHECK-LABEL: Function: noop_callee
+; CHECK: MayAlias: i32* %arg1, i32* %arg2
+define void @noop_callee(i32* %arg1, i32* %arg2) {
+ store i32 0, i32* %arg1
+ store i32 0, i32* %arg2
+ ret void
+}
+; CHECK-LABEL: Function: test_noop
+; CHECK: NoAlias: i32* %a, i32* %b
+define void @test_noop() {
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+ call void @noop_callee(i32* %a, i32* %b)
+
+ ret void
+}
diff --git a/test/Analysis/CFLAliasAnalysis/branch-alias.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/branch-alias.ll
index dbbf035f34401..4158d4a6464f2 100644
--- a/test/Analysis/CFLAliasAnalysis/branch-alias.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/branch-alias.ll
@@ -13,7 +13,7 @@
; int* ShouldAliasA = *AliasA1;
; }
-; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
; CHECK: Function: ptr_test
define void @ptr_test() #0 {
diff --git a/test/Analysis/CFLAliasAnalysis/const-expr-gep.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/const-expr-gep.ll
index 11b60dd33b55e..c35f6a03cdb9b 100644
--- a/test/Analysis/CFLAliasAnalysis/const-expr-gep.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/const-expr-gep.ll
@@ -1,8 +1,8 @@
; This testcase consists of alias relations which should be completely
-; resolvable by cfl-aa, but require analysis of getelementptr constant exprs.
+; resolvable by cfl-steens-aa, but require analysis of getelementptr constant exprs.
; Derived from BasicAA/2003-12-11-ConstExprGEP.ll
-; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
%T = type { i32, [10 x i8] }
@@ -10,7 +10,7 @@
@G2 = external global %T
; TODO: Quite a few of these are MayAlias because we don't yet consider
-; constant offsets in CFLAA. If we start doing so, then we'll need to
+; constant offsets in CFLSteensAA. If we start doing so, then we'll need to
; change these test cases
; CHECK: Function: test
@@ -36,7 +36,7 @@ define void @simplecheck(i32* %arg0) {
ret void
}
-; Ensure that CFLAA properly identifies and handles escaping variables (i.e.
+; Ensure that CFLSteensAA properly identifies and handles escaping variables (i.e.
; globals) in nested ConstantExprs
; CHECK: Function: checkNesting
diff --git a/test/Analysis/CFLAliasAnalysis/constant-over-index.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/constant-over-index.ll
index a8e00aaed3786..09e62fcd85a43 100644
--- a/test/Analysis/CFLAliasAnalysis/constant-over-index.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/constant-over-index.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -cfl-aa -aa-eval -print-all-alias-modref-info 2>&1 | FileCheck %s
+; RUN: opt < %s -cfl-steens-aa -aa-eval -print-all-alias-modref-info 2>&1 | FileCheck %s
; CFL AA currently returns PartialAlias, BasicAA returns MayAlias, both seem
; acceptable (although we might decide that we don't want PartialAlias, and if
diff --git a/test/Analysis/CFLAliasAnalysis/empty.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/empty.ll
index 907fa481d86d4..f8714de2c2fe7 100644
--- a/test/Analysis/CFLAliasAnalysis/empty.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/empty.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -cfl-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
diff --git a/test/Analysis/CFLAliasAnalysis/full-store-partial-alias.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/full-store-partial-alias.ll
index 3503e16898c08..39ea845f2a3a3 100644
--- a/test/Analysis/CFLAliasAnalysis/full-store-partial-alias.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/full-store-partial-alias.ll
@@ -1,10 +1,10 @@
-; RUN: opt -S -disable-basicaa -tbaa -cfl-aa -gvn < %s | FileCheck -check-prefix=CFLAA %s
+; RUN: opt -S -disable-basicaa -tbaa -cfl-steens-aa -gvn < %s | FileCheck -check-prefix=CFLSteensAA %s
; RUN: opt -S -disable-basicaa -tbaa -gvn < %s | FileCheck %s
; Adapted from the BasicAA full-store-partial-alias.ll test.
; CFL AA could notice that the store stores to the entire %u object,
; so the %tmp5 load is PartialAlias with the store and suppress TBAA.
-; FIXME: However, right now, CFLAA cannot prove PartialAlias here
+; FIXME: However, right now, CFLSteensAA cannot prove PartialAlias here
; Without CFL AA, TBAA should say that %tmp5 is NoAlias with the store.
target datalayout = "e-p:64:64:64"
@@ -15,8 +15,8 @@ target datalayout = "e-p:64:64:64"
@endianness_test = global i64 1, align 8
define i32 @signbit(double %x) nounwind {
-; FIXME: This would be ret i32 %tmp5.lobit if CFLAA could prove PartialAlias
-; CFLAA: ret i32 0
+; FIXME: This would be ret i32 %tmp5.lobit if CFLSteensAA could prove PartialAlias
+; CFLSteensAA: ret i32 0
; CHECK: ret i32 0
entry:
%u = alloca %union.anon, align 8
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/gep-index-no-alias.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/gep-index-no-alias.ll
new file mode 100644
index 0000000000000..906b71c5aab32
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/gep-index-no-alias.ll
@@ -0,0 +1,14 @@
+; This testcase ensures that gep result does not alias gep indices
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-no-aliases -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-no-aliases -disable-output 2>&1 | FileCheck %s
+
+; CHECK: Function: foo
+; CHECK: [2 x i32]* %a, [2 x i32]* %b
+define void @foo(i32 %n) {
+ %a = alloca [2 x i32], align 4
+ %b = alloca [2 x i32], align 4
+ %c = getelementptr inbounds [2 x i32], [2 x i32]* %a, i32 0, i32 %n
+ %d = getelementptr inbounds [2 x i32], [2 x i32]* %b, i32 0, i32 %n
+ ret void
+}
diff --git a/test/Analysis/CFLAliasAnalysis/gep-signed-arithmetic.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/gep-signed-arithmetic.ll
index 1edbb9fff56b1..34095cedf7387 100644
--- a/test/Analysis/CFLAliasAnalysis/gep-signed-arithmetic.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/gep-signed-arithmetic.ll
@@ -1,9 +1,9 @@
-; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
; Derived from BasicAA/2010-09-15-GEP-SignedArithmetic.ll
target datalayout = "e-p:32:32:32"
-; FIXME: This could be PartialAlias but CFLAA can't currently prove it
+; FIXME: This could be PartialAlias but CFLSteensAA can't currently prove it
; CHECK: 1 may alias response
define i32 @test(i32 %indvar) nounwind {
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-arg-deref-escape.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-arg-deref-escape.ll
new file mode 100644
index 0000000000000..8c92d281a80b7
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-arg-deref-escape.ll
@@ -0,0 +1,33 @@
+; This testcase ensures that CFL AA answers queries soundly when callee tries
+; to escape the memory pointed to by its parameters
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+declare void @opaque(i32*)
+define void @escape_arg_deref(i32** %arg) {
+ %arg_deref = load i32*, i32** %arg
+ call void @opaque(i32* %arg_deref)
+ ret void
+}
+; CHECK-LABEL: Function: test_arg_deref_escape
+; CHECK: NoAlias: i32* %a, i32** %x
+; CHECK: NoAlias: i32* %b, i32** %x
+; CHECK: NoAlias: i32* %a, i32* %b
+; CHECK: NoAlias: i32** %p, i32** %x
+; CHECK: NoAlias: i32* %a, i32** %p
+; CHECK: NoAlias: i32* %b, i32** %p
+; CHECK: MayAlias: i32* %a, i32* %c
+; CHECK: NoAlias: i32* %b, i32* %c
+; CHECK: NoAlias: i32* %c, i32** %p
+define void @test_arg_deref_escape(i32** %x) {
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+ %p = alloca i32*, align 4
+
+ store i32* %a, i32** %p
+ call void @escape_arg_deref(i32** %p)
+ %c = load i32*, i32** %x
+
+ ret void
+} \ No newline at end of file
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-arg-escape.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-arg-escape.ll
new file mode 100644
index 0000000000000..0dfcae7920335
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-arg-escape.ll
@@ -0,0 +1,31 @@
+; This testcase ensures that CFL AA answers queries soundly when callee tries
+; to escape its parameters
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+declare void @opaque(i32*)
+define void @escape_arg(i32* %arg) {
+ call void @opaque(i32* %arg)
+ ret void
+}
+; CHECK-LABEL: Function: test_arg_escape
+; CHECK: NoAlias: i32* %a, i32** %x
+; CHECK: NoAlias: i32* %b, i32** %x
+; CHECK: NoAlias: i32* %a, i32* %b
+; CHECK: NoAlias: i32* %c, i32** %x
+; CHECK: NoAlias: i32* %a, i32* %c
+; CHECK: NoAlias: i32* %b, i32* %c
+; CHECK: MayAlias: i32* %a, i32* %d
+; CHECK: MayAlias: i32* %b, i32* %d
+; CHECK: NoAlias: i32* %c, i32* %d
+define void @test_arg_escape(i32** %x) {
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+ %c = alloca i32, align 4
+ call void @escape_arg(i32* %a)
+ call void @escape_arg(i32* %b)
+ %d = load i32*, i32** %x
+
+ ret void
+} \ No newline at end of file
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-arg.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-arg.ll
new file mode 100644
index 0000000000000..e071e7e46c25a
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-arg.ll
@@ -0,0 +1,23 @@
+; This testcase ensures that CFL AA answers queries soundly when callee tries
+; to return one of its parameters
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+define i32* @return_arg_callee(i32* %arg1, i32* %arg2) {
+ ret i32* %arg1
+}
+; CHECK-LABEL: Function: test_return_arg
+; CHECK: NoAlias: i32* %a, i32* %b
+; CHECK: MayAlias: i32* %a, i32* %c
+; CHECK: NoAlias: i32* %b, i32* %c
+
+; CHECK: NoModRef: Ptr: i32* %b <-> %c = call i32* @return_arg_callee(i32* %a, i32* %b)
+define void @test_return_arg() {
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+
+ %c = call i32* @return_arg_callee(i32* %a, i32* %b)
+
+ ret void
+} \ No newline at end of file
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-deref-arg-multilevel.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-deref-arg-multilevel.ll
new file mode 100644
index 0000000000000..3c7c614998296
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-deref-arg-multilevel.ll
@@ -0,0 +1,46 @@
+; This testcase ensures that CFL AA answers queries soundly when callee tries
+; to return the multi-level dereference of one of its parameters
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+define i32* @return_deref_arg_multilevel_callee(i32*** %arg1) {
+ %deref = load i32**, i32*** %arg1
+ %deref2 = load i32*, i32** %deref
+ ret i32* %deref2
+}
+; CHECK-LABEL: Function: test_return_deref_arg_multilevel
+; CHECK: NoAlias: i32* %a, i32* %b
+; CHECK: MayAlias: i32* %a, i32* %c
+; CHECK: NoAlias: i32* %b, i32* %c
+; CHECK: NoAlias: i32* %c, i32** %p
+; CHECK: NoAlias: i32* %c, i32*** %pp
+; CHECK: MayAlias: i32** %lpp, i32** %p
+; CHECK: NoAlias: i32** %lpp, i32*** %pp
+; CHECK: NoAlias: i32* %c, i32** %lpp
+; CHECK: MayAlias: i32* %a, i32* %lpp_deref
+; CHECK: NoAlias: i32* %b, i32* %lpp_deref
+; CHECK: NoAlias: i32* %lpp_deref, i32*** %pp
+; CHECK: MayAlias: i32* %a, i32* %lp
+; CHECK: NoAlias: i32* %b, i32* %lp
+; CHECK: NoAlias: i32* %lp, i32** %p
+; CHECK: NoAlias: i32* %lp, i32*** %pp
+; CHECK: MayAlias: i32* %c, i32* %lp
+; CHECK: NoAlias: i32* %lp, i32** %lpp
+; CHECK: MayAlias: i32* %lp, i32* %lpp_deref
+define void @test_return_deref_arg_multilevel() {
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+ %p = alloca i32*, align 8
+ %pp = alloca i32**, align 8
+
+ store i32* %a, i32** %p
+ store i32** %p, i32*** %pp
+ %c = call i32* @return_deref_arg_multilevel_callee(i32*** %pp)
+
+ %lpp = load i32**, i32*** %pp
+ %lpp_deref = load i32*, i32** %lpp
+ %lp = load i32*, i32** %p
+
+ ret void
+} \ No newline at end of file
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-deref-arg.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-deref-arg.ll
new file mode 100644
index 0000000000000..e1db5d34f3490
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-deref-arg.ll
@@ -0,0 +1,30 @@
+; This testcase ensures that CFL AA answers queries soundly when callee tries
+; to return the dereference of one of its parameters
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+define i32* @return_deref_arg_callee(i32** %arg1) {
+ %deref = load i32*, i32** %arg1
+ ret i32* %deref
+}
+; CHECK-LABEL: Function: test_return_deref_arg
+; CHECK: NoAlias: i32* %a, i32* %b
+; CHECK: MayAlias: i32* %a, i32* %c
+; CHECK: NoAlias: i32* %b, i32* %c
+; CHECK: MayAlias: i32* %a, i32* %lp
+; CHECK: NoAlias: i32* %b, i32* %lp
+; CHECK: NoAlias: i32* %lp, i32** %p
+; CHECK: MayAlias: i32* %c, i32* %lp
+define void @test_return_deref_arg() {
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+ %p = alloca i32*, align 8
+
+ store i32* %a, i32** %p
+ %c = call i32* @return_deref_arg_callee(i32** %p)
+
+ %lp = load i32*, i32** %p
+
+ ret void
+} \ No newline at end of file
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-escape.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-escape.ll
new file mode 100644
index 0000000000000..5019e51d7b8bf
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-escape.ll
@@ -0,0 +1,33 @@
+; This testcase ensures that CFL AA answers queries soundly when callee tries
+; to return an escaped pointer
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+declare noalias i8* @malloc(i64)
+declare void @opaque(i32*)
+
+define i32* @return_escaped_callee() {
+ %ptr = call noalias i8* @malloc(i64 8)
+ %ptr_cast = bitcast i8* %ptr to i32*
+ call void @opaque(i32* %ptr_cast)
+ ret i32* %ptr_cast
+}
+; CHECK-LABEL: Function: test_return_escape
+; CHECK: NoAlias: i32* %a, i32** %x
+; CHECK: NoAlias: i32* %b, i32** %x
+; CHECK: NoAlias: i32* %a, i32* %b
+; CHECK: NoAlias: i32* %c, i32** %x
+; CHECK: NoAlias: i32* %a, i32* %c
+; CHECK: NoAlias: i32* %b, i32* %c
+; CHECK: NoAlias: i32* %a, i32* %d
+; CHECK: MayAlias: i32* %b, i32* %d
+; CHECK: MayAlias: i32* %c, i32* %d
+define void @test_return_escape(i32** %x) {
+ %a = alloca i32, align 4
+ %b = call i32* @return_escaped_callee()
+ %c = call i32* @return_escaped_callee()
+ %d = load i32*, i32** %x
+
+ ret void
+} \ No newline at end of file
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-ref-arg-multilevel.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-ref-arg-multilevel.ll
new file mode 100644
index 0000000000000..e94cbbbdf30e1
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-ref-arg-multilevel.ll
@@ -0,0 +1,51 @@
+; This testcase ensures that CFL AA answers queries soundly when callee tries
+; to return the multi-level reference of one of its parameters
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+declare noalias i8* @malloc(i64)
+
+define i32*** @return_ref_arg_multilevel_callee(i32* %arg1) {
+ %ptr = call noalias i8* @malloc(i64 8)
+ %ptr_cast = bitcast i8* %ptr to i32***
+ %ptr2 = call noalias i8* @malloc(i64 8)
+ %ptr_cast2 = bitcast i8* %ptr2 to i32**
+ store i32* %arg1, i32** %ptr_cast2
+ store i32** %ptr_cast2, i32*** %ptr_cast
+ ret i32*** %ptr_cast
+}
+; CHECK-LABEL: Function: test_return_ref_arg_multilevel
+; CHECK: NoAlias: i32* %a, i32*** %b
+; CHECK: NoAlias: i32** %p, i32*** %b
+; CHECK: NoAlias: i32* %a, i32** %lb
+; CHECK: NoAlias: i32** %lb, i32*** %pp
+; CHECK: NoAlias: i32** %lb, i32*** %b
+; CHECK: MayAlias: i32* %a, i32* %lb_deref
+; CHECK: NoAlias: i32* %lb_deref, i32** %lpp
+; CHECK: MayAlias: i32* %lb_deref, i32* %lpp_deref
+; CHECK: NoAlias: i32* %lpp_deref, i32** %lpp
+; CHECK: MayAlias: i32* %lb_deref, i32* %lp
+; CHECK: NoAlias: i32* %lp, i32** %lpp
+; CHECK: MayAlias: i32* %lp, i32* %lpp_deref
+
+; We could've proven the following facts if the analysis were inclusion-based:
+; NoAlias: i32*** %b, i32*** %pp
+; NoAlias: i32** %lb, i32** %p
+define void @test_return_ref_arg_multilevel() {
+ %a = alloca i32, align 4
+ %p = alloca i32*, align 8
+ %pp = alloca i32**, align 8
+
+ store i32* %a, i32** %p
+ store i32** %p, i32*** %pp
+ %b = call i32*** @return_ref_arg_multilevel_callee(i32* %a)
+
+ %lb = load i32**, i32*** %b
+ %lb_deref = load i32*, i32** %lb
+ %lpp = load i32**, i32*** %pp
+ %lpp_deref = load i32*, i32** %lpp
+ %lp = load i32*, i32** %p
+
+ ret void
+} \ No newline at end of file
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-ref-arg.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-ref-arg.ll
new file mode 100644
index 0000000000000..aae642c424da3
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-ref-arg.ll
@@ -0,0 +1,36 @@
+; This testcase ensures that CFL AA answers queries soundly when callee tries
+; to return the reference of one of its parameters
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+declare noalias i8* @malloc(i64)
+
+define i32** @return_ref_arg_callee(i32* %arg1) {
+ %ptr = call noalias i8* @malloc(i64 8)
+ %ptr_cast = bitcast i8* %ptr to i32**
+ store i32* %arg1, i32** %ptr_cast
+ ret i32** %ptr_cast
+}
+; CHECK-LABEL: Function: test_return_ref_arg
+; CHECK: MayAlias: i32* %a, i32* %lb
+; CHECK: NoAlias: i32* %lb, i32** %p
+; CHECK: NoAlias: i32* %lb, i32** %b
+; CHECK: NoAlias: i32* %lp, i32** %p
+; CHECK: NoAlias: i32* %lp, i32** %b
+; CHECK: MayAlias: i32* %lb, i32* %lp
+
+; We could've proven the following facts if the analysis were inclusion-based:
+; NoAlias: i32** %b, i32** %p
+define void @test_return_ref_arg() {
+ %a = alloca i32, align 4
+ %p = alloca i32*, align 8
+
+ store i32* %a, i32** %p
+ %b = call i32** @return_ref_arg_callee(i32* %a)
+
+ %lb = load i32*, i32** %b
+ %lp = load i32*, i32** %p
+
+ ret void
+} \ No newline at end of file
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-unknown.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-unknown.ll
new file mode 100644
index 0000000000000..bc4a9bc901bc4
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-ret-unknown.ll
@@ -0,0 +1,38 @@
+; This testcase ensures that CFL AA answers queries soundly when callee tries
+; to return an unknown pointer
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+@g = external global i32
+define i32* @return_unknown_callee(i32* %arg1, i32* %arg2) {
+ ret i32* @g
+}
+; CHECK-LABEL: Function: test_return_unknown
+; CHECK: NoAlias: i32* %a, i32* %b
+; CHECK: MayAlias: i32* %c, i32* %x
+; CHECK: NoAlias: i32* %a, i32* %c
+; CHECK: NoAlias: i32* %b, i32* %c
+define void @test_return_unknown(i32* %x) {
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+
+ %c = call i32* @return_unknown_callee(i32* %a, i32* %b)
+
+ ret void
+}
+
+@g2 = external global i32*
+define i32** @return_unknown_callee2() {
+ ret i32** @g2
+}
+; CHECK-LABEL: Function: test_return_unknown2
+; CHECK: MayAlias: i32* %x, i32** %a
+; CHECK: MayAlias: i32* %b, i32* %x
+; CHECK: MayAlias: i32* %b, i32** %a
+define void @test_return_unknown2(i32* %x) {
+ %a = call i32** @return_unknown_callee2()
+ %b = load i32*, i32** %a
+
+ ret void
+} \ No newline at end of file
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-store-arg-multilevel.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-store-arg-multilevel.ll
new file mode 100644
index 0000000000000..f5b61687ad700
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-store-arg-multilevel.ll
@@ -0,0 +1,48 @@
+; This testcase ensures that CFL AA answers queries soundly when callee tries
+; to mutate the memory pointed to by its parameters
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+declare noalias i8* @malloc(i64)
+
+define void @store_arg_multilevel_callee(i32*** %arg1, i32* %arg2) {
+ %ptr = call noalias i8* @malloc(i64 8)
+ %ptr_cast = bitcast i8* %ptr to i32**
+ store i32* %arg2, i32** %ptr_cast
+ store i32** %ptr_cast, i32*** %arg1
+ ret void
+}
+; CHECK-LABEL: Function: test_store_arg_multilevel
+; CHECK: NoAlias: i32* %a, i32** %lpp
+; CHECK: NoAlias: i32* %b, i32** %lpp
+; CHECK: MayAlias: i32** %lpp, i32** %p
+; CHECK: MayAlias: i32* %a, i32* %lpp_deref
+; CHECK: MayAlias: i32* %b, i32* %lpp_deref
+; CHECK: NoAlias: i32* %lpp_deref, i32** %p
+; CHECK: NoAlias: i32* %lpp_deref, i32*** %pp
+; CHECK: NoAlias: i32* %lpp_deref, i32** %lpp
+; CHECK: MayAlias: i32* %a, i32* %lp
+; CHECK: NoAlias: i32* %lp, i32*** %pp
+; CHECK: NoAlias: i32* %lp, i32** %lpp
+; CHECK: MayAlias: i32* %lp, i32* %lpp_deref
+
+; We could've proven the following facts if the analysis were inclusion-based:
+; NoAlias: i32* %a, i32* %b
+; NoAlias: i32* %b, i32* %lp
+define void @test_store_arg_multilevel() {
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+ %p = alloca i32*, align 8
+ %pp = alloca i32**, align 8
+
+ store i32* %a, i32** %p
+ store i32** %p, i32*** %pp
+ call void @store_arg_multilevel_callee(i32*** %pp, i32* %b)
+
+ %lpp = load i32**, i32*** %pp
+ %lpp_deref = load i32*, i32** %lpp
+ %lp = load i32*, i32** %p
+
+ ret void
+} \ No newline at end of file
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-store-arg-unknown.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-store-arg-unknown.ll
new file mode 100644
index 0000000000000..a90514c58fa95
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-store-arg-unknown.ll
@@ -0,0 +1,32 @@
+; This testcase ensures that CFL AA answers queries soundly when callee tries
+; to mutate the memory pointed to by its parameters
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+@g = external global i32
+
+define void @store_arg_unknown_callee(i32** %arg1) {
+ store i32* @g, i32** %arg1
+ ret void
+}
+; CHECK-LABEL: Function: test_store_arg_unknown
+; CHECK: NoAlias: i32* %x, i32** %p
+; CHECK: NoAlias: i32* %a, i32** %p
+; CHECK: NoAlias: i32* %b, i32** %p
+; CHECK: MayAlias: i32* %lp, i32* %x
+; CHECK: MayAlias: i32* %a, i32* %lp
+; CHECK: NoAlias: i32* %b, i32* %lp
+; CHECK: NoAlias: i32* %lp, i32** %p
+define void @test_store_arg_unknown(i32* %x) {
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+ %p = alloca i32*, align 8
+
+ store i32* %a, i32** %p
+ call void @store_arg_unknown_callee(i32** %p)
+
+ %lp = load i32*, i32** %p
+
+ ret void
+} \ No newline at end of file
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-store-arg.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-store-arg.ll
new file mode 100644
index 0000000000000..e520de4d0b1c1
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/interproc-store-arg.ll
@@ -0,0 +1,36 @@
+; This testcase ensures that CFL AA answers queries soundly when callee tries
+; to mutate the memory pointed to by its parameters
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+
+define void @store_arg_callee(i32** %arg1, i32* %arg2) {
+ store i32* %arg2, i32** %arg1
+ ret void
+}
+; CHECK-LABEL: Function: test_store_arg
+; CHECK: NoAlias: i32* %a, i32** %p
+; CHECK: NoAlias: i32* %b, i32** %p
+; CHECK: MayAlias: i32* %a, i32* %lp
+; CHECK: MayAlias: i32* %b, i32* %lp
+; CHECK: MayAlias: i32* %b, i32* %lq
+; CHECK: MayAlias: i32* %lp, i32* %lq
+
+; We could've proven the following facts if the analysis were inclusion-based:
+; NoAlias: i32* %a, i32* %b
+; NoAlias: i32* %a, i32* %lq
+define void @test_store_arg() {
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+ %p = alloca i32*, align 8
+ %q = alloca i32*, align 8
+
+ store i32* %a, i32** %p
+ store i32* %b, i32** %q
+ call void @store_arg_callee(i32** %p, i32* %b)
+
+ %lp = load i32*, i32** %p
+ %lq = load i32*, i32** %q
+
+ ret void
+} \ No newline at end of file
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/malloc-and-free.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/malloc-and-free.ll
new file mode 100644
index 0000000000000..76c97db8038c7
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/malloc-and-free.ll
@@ -0,0 +1,30 @@
+; This testcase ensures that CFL AA handles malloc and free in a sound and precise manner
+
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-no-aliases -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-no-aliases -disable-output 2>&1 | FileCheck %s
+
+declare noalias i8* @malloc(i64)
+declare noalias i8* @calloc(i64, i64)
+declare void @free(i8* nocapture)
+
+; CHECK: Function: test_malloc
+; CHECK: NoAlias: i8* %p, i8* %q
+define void @test_malloc(i8* %p) {
+ %q = call i8* @malloc(i64 4)
+ ret void
+}
+
+; CHECK: Function: test_calloc
+; CHECK: NoAlias: i8* %p, i8* %q
+define void @test_calloc(i8* %p) {
+ %q = call i8* @calloc(i64 2, i64 4)
+ ret void
+}
+
+; CHECK: Function: test_free
+; CHECK: NoAlias: i8* %p, i8* %q
+define void @test_free(i8* %p) {
+ %q = alloca i8, align 4
+ call void @free(i8* %q)
+ ret void
+}
diff --git a/test/Analysis/CFLAliasAnalysis/multilevel-combine.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/multilevel-combine.ll
index be671bfc4ca27..32abe9d8f744c 100644
--- a/test/Analysis/CFLAliasAnalysis/multilevel-combine.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/multilevel-combine.ll
@@ -8,7 +8,7 @@
; }
;
-; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
%T = type { i32, [10 x i8] }
diff --git a/test/Analysis/CFLAliasAnalysis/multilevel.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/multilevel.ll
index d42dca442eab0..ea06b7430bcdb 100644
--- a/test/Analysis/CFLAliasAnalysis/multilevel.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/multilevel.ll
@@ -6,7 +6,7 @@
; *m;
; *n;
-; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -cfl-steens-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
%T = type { i32, [10 x i8] }
diff --git a/test/Analysis/CFLAliasAnalysis/must-and-partial.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/must-and-partial.ll
index 5bcc3f9910224..cc03870b79485 100644
--- a/test/Analysis/CFLAliasAnalysis/must-and-partial.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/must-and-partial.ll
@@ -1,11 +1,11 @@
-; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-all-alias-modref-info 2>&1 | FileCheck %s
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info 2>&1 | FileCheck %s
; When merging MustAlias and PartialAlias, merge to PartialAlias
; instead of MayAlias.
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"
-; FIXME: This could be PartialAlias but CFLAA can't currently prove it
+; FIXME: This could be PartialAlias but CFLSteensAA can't currently prove it
; CHECK: MayAlias: i16* %bigbase0, i8* %phi
define i8 @test0(i1 %x) {
entry:
@@ -25,7 +25,7 @@ green:
ret i8 %loaded
}
-; FIXME: This could be PartialAlias but CFLAA can't currently prove it
+; FIXME: This could be PartialAlias but CFLSteensAA can't currently prove it
; CHECK: MayAlias: i16* %bigbase1, i8* %sel
define i8 @test1(i1 %x) {
entry:
diff --git a/test/Analysis/CFLAliasAnalysis/opaque-call-alias.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/opaque-call-alias.ll
index 6121dca1345dd..a03b104778bdf 100644
--- a/test/Analysis/CFLAliasAnalysis/opaque-call-alias.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/opaque-call-alias.ll
@@ -2,10 +2,10 @@
; its own stratified set. This would make cases like the one in @test say that
; nothing (except %Escapes and %Arg) can alias
-; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
; CHECK: Function: test
-; CHECK: MayAlias: i8* %Arg, i8* %Escapes
+; CHECK: NoAlias: i8* %Arg, i8* %Escapes
; CHECK: MayAlias: i8* %Arg, i8* %Retrieved
; CHECK: MayAlias: i8* %Escapes, i8* %Retrieved
define void @test(i8* %Arg) {
diff --git a/test/Analysis/CFLAliasAnalysis/phi-and-select.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/phi-and-select.ll
index a0e71a7e7dcae..2af7fdea02c5e 100644
--- a/test/Analysis/CFLAliasAnalysis/phi-and-select.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/phi-and-select.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -cfl-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
; Derived from (a subset of) BasicAA/phi-and-select.ll
; CHECK: Function: qux
diff --git a/test/Analysis/CFLAliasAnalysis/Steensgaard/pr27213.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/pr27213.ll
new file mode 100644
index 0000000000000..d685cab6275e8
--- /dev/null
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/pr27213.ll
@@ -0,0 +1,39 @@
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+
+; CHECK-LABEL: Function: foo
+; CHECK: MayAlias: i32* %A, i32* %B
+define void @foo(i32* %A, i32* %B) {
+entry:
+ store i32 0, i32* %A, align 4
+ store i32 0, i32* %B, align 4
+ ret void
+}
+
+; CHECK-LABEL: Function: bar
+; CHECK: MayAlias: i32* %A, i32* %B
+; CHECK: MayAlias: i32* %A, i32* %arrayidx
+; CHECK: MayAlias: i32* %B, i32* %arrayidx
+define void @bar(i32* %A, i32* %B) {
+entry:
+ store i32 0, i32* %A, align 4
+ %arrayidx = getelementptr inbounds i32, i32* %B, i64 1
+ store i32 0, i32* %arrayidx, align 4
+ ret void
+}
+
+@G = global i32 0
+
+; CHECK-LABEL: Function: baz
+; CHECK: MayAlias: i32* %A, i32* @G
+define void @baz(i32* %A) {
+entry:
+ store i32 0, i32* %A, align 4
+ store i32 0, i32* @G, align 4
+ ret void
+}
+
+; CHECK-LABEL: Alias Analysis Evaluator Report
+; CHECK: 5 Total Alias Queries Performed
+; CHECK: 0 no alias responses
+; CHECK: 5 may alias responses
diff --git a/test/Analysis/CFLAliasAnalysis/simple.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/simple.ll
index adc71867bfc14..17b48d48b0f24 100644
--- a/test/Analysis/CFLAliasAnalysis/simple.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/simple.ll
@@ -1,7 +1,7 @@
; This testcase consists of alias relations which should be completely
-; resolvable by cfl-aa (derived from BasicAA/2003-11-04-SimpleCases.ll).
+; resolvable by cfl-steens-aa (derived from BasicAA/2003-11-04-SimpleCases.ll).
-; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -cfl-steens-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
%T = type { i32, [10 x i8] }
diff --git a/test/Analysis/CFLAliasAnalysis/stratified-attrs-indexing.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/stratified-attrs-indexing.ll
index 347528583a610..f43af93e99481 100644
--- a/test/Analysis/CFLAliasAnalysis/stratified-attrs-indexing.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/stratified-attrs-indexing.ll
@@ -1,11 +1,11 @@
-; This testcase ensures that CFLAA doesn't try to access out of bounds indices
+; This testcase ensures that CFLSteensAA doesn't try to access out of bounds indices
; when given functions with large amounts of arguments (specifically, more
; arguments than the StratifiedAttrs bitset can handle)
;
; Because the result on failure is effectively crashing the compiler, output
; checking is minimal.
-; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -cfl-steens-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
; CHECK: Function: test
define void @test(i1 %cond,
diff --git a/test/Analysis/CFLAliasAnalysis/va.ll b/test/Analysis/CFLAliasAnalysis/Steensgaard/va.ll
index a432cea8a1dfb..43fca92074127 100644
--- a/test/Analysis/CFLAliasAnalysis/va.ll
+++ b/test/Analysis/CFLAliasAnalysis/Steensgaard/va.ll
@@ -1,16 +1,19 @@
-; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -disable-basicaa -cfl-steens-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
; CHECK-LABEL: Function: test1
-; CHECK: 0 no alias responses
+; CHECK: MayAlias: i32* %X, i32* %tmp
+; CHECK: MayAlias: i32* %tmp, i8** %ap
+; CHECK: NoAlias: i8** %ap, i8** %aq
+; CHECK: MayAlias: i32* %tmp, i8** %aq
-define i32 @test1(i32 %X, ...) {
+define i32* @test1(i32* %X, ...) {
; Initialize variable argument processing
%ap = alloca i8*
%ap2 = bitcast i8** %ap to i8*
call void @llvm.va_start(i8* %ap2)
- ; Read a single integer argument
- %tmp = va_arg i8** %ap, i32
+ ; Read a single pointer argument
+ %tmp = va_arg i8** %ap, i32*
; Demonstrate usage of llvm.va_copy and llvm.va_end
%aq = alloca i8*
@@ -20,7 +23,7 @@ define i32 @test1(i32 %X, ...) {
; Stop processing of arguments.
call void @llvm.va_end(i8* %ap2)
- ret i32 %tmp
+ ret i32* %tmp
}
declare void @llvm.va_start(i8*)
diff --git a/test/Analysis/CFLAliasAnalysis/basic-interproc-ret.ll b/test/Analysis/CFLAliasAnalysis/basic-interproc-ret.ll
deleted file mode 100644
index d56a4552b51e1..0000000000000
--- a/test/Analysis/CFLAliasAnalysis/basic-interproc-ret.ll
+++ /dev/null
@@ -1,26 +0,0 @@
-; This testcase ensures that CFL AA gives conservative answers on variables
-; that involve arguments.
-
-; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
-
-; CHECK: Function: test
-; CHECK: 4 Total Alias Queries Performed
-; CHECK: 3 no alias responses
-; ^ The 1 MayAlias is due to %arg1. Sadly, we don't currently have machinery
-; in place to check whether %arg1 aliases %a, because BasicAA takes care of
-; that for us.
-
-define i32* @test2(i32* %arg1) {
- store i32 0, i32* %arg1
-
- %a = alloca i32, align 4
- ret i32* %a
-}
-
-define void @test() {
- %a = alloca i32, align 4
- %b = alloca i32, align 4
- %c = call i32* @test2(i32* %a)
-
- ret void
-}
diff --git a/test/Analysis/CFLAliasAnalysis/basic-interproc.ll b/test/Analysis/CFLAliasAnalysis/basic-interproc.ll
deleted file mode 100644
index d6515eb9ebe51..0000000000000
--- a/test/Analysis/CFLAliasAnalysis/basic-interproc.ll
+++ /dev/null
@@ -1,24 +0,0 @@
-; This testcase ensures that CFL AA gives conservative answers on variables
-; that involve arguments.
-
-; RUN: opt < %s -disable-basicaa -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
-
-; CHECK: Function: test
-; CHECK: 2 Total Alias Queries Performed
-; CHECK: 1 no alias responses
-; ^^ In @test2, %arg1 and %arg2 may alias
-
-define void @test2(i32* %arg1, i32* %arg2) {
- store i32 0, i32* %arg1
- store i32 0, i32* %arg2
-
- ret void
-}
-
-define void @test() {
- %a = alloca i32, align 4
- %b = alloca i32, align 4
- call void @test2(i32* %a, i32* %b)
-
- ret void
-}
diff --git a/test/Analysis/CallGraph/no-intrinsics.ll b/test/Analysis/CallGraph/no-intrinsics.ll
index d858907d7247b..69bfce7791851 100644
--- a/test/Analysis/CallGraph/no-intrinsics.ll
+++ b/test/Analysis/CallGraph/no-intrinsics.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -print-callgraph -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -passes=print-callgraph -disable-output 2>&1 | FileCheck %s
; Check that intrinsics aren't added to the call graph
diff --git a/test/Analysis/CostModel/AArch64/kryo.ll b/test/Analysis/CostModel/AArch64/kryo.ll
new file mode 100644
index 0000000000000..4b916a286ea09
--- /dev/null
+++ b/test/Analysis/CostModel/AArch64/kryo.ll
@@ -0,0 +1,26 @@
+; RUN: opt < %s -cost-model -analyze -mcpu=kryo | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64--linux-gnu"
+
+; CHECK-LABEL: vectorInstrCost
+define void @vectorInstrCost() {
+
+ ; Vector extracts - extracting the first element should have a zero cost;
+ ; all other elements should have a cost of two.
+ ;
+ ; CHECK: cost of 0 {{.*}} extractelement <2 x i64> undef, i32 0
+ ; CHECK: cost of 2 {{.*}} extractelement <2 x i64> undef, i32 1
+ %t1 = extractelement <2 x i64> undef, i32 0
+ %t2 = extractelement <2 x i64> undef, i32 1
+
+ ; Vector inserts - inserting the first element should have a zero cost; all
+ ; other elements should have a cost of two.
+ ;
+ ; CHECK: cost of 0 {{.*}} insertelement <2 x i64> undef, i64 undef, i32 0
+ ; CHECK: cost of 2 {{.*}} insertelement <2 x i64> undef, i64 undef, i32 1
+ %t3 = insertelement <2 x i64> undef, i64 undef, i32 0
+ %t4 = insertelement <2 x i64> undef, i64 undef, i32 1
+
+ ret void
+}
diff --git a/test/Analysis/CostModel/AMDGPU/add-sub.ll b/test/Analysis/CostModel/AMDGPU/add-sub.ll
new file mode 100644
index 0000000000000..76b21d26faaa4
--- /dev/null
+++ b/test/Analysis/CostModel/AMDGPU/add-sub.ll
@@ -0,0 +1,138 @@
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa -mattr=+half-rate-64-ops < %s | FileCheck %s
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa -mattr=-half-rate-64-ops < %s | FileCheck %s
+
+; CHECK: 'add_i32'
+; CHECK: estimated cost of 1 for {{.*}} add i32
+define void @add_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %vaddr, i32 %b) #0 {
+ %vec = load i32, i32 addrspace(1)* %vaddr
+ %add = add i32 %vec, %b
+ store i32 %add, i32 addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'add_v2i32'
+; CHECK: estimated cost of 2 for {{.*}} add <2 x i32>
+define void @add_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> addrspace(1)* %vaddr, <2 x i32> %b) #0 {
+ %vec = load <2 x i32>, <2 x i32> addrspace(1)* %vaddr
+ %add = add <2 x i32> %vec, %b
+ store <2 x i32> %add, <2 x i32> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'add_v3i32'
+; CHECK: estimated cost of 3 for {{.*}} add <3 x i32>
+define void @add_v3i32(<3 x i32> addrspace(1)* %out, <3 x i32> addrspace(1)* %vaddr, <3 x i32> %b) #0 {
+ %vec = load <3 x i32>, <3 x i32> addrspace(1)* %vaddr
+ %add = add <3 x i32> %vec, %b
+ store <3 x i32> %add, <3 x i32> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'add_v4i32'
+; CHECK: estimated cost of 4 for {{.*}} add <4 x i32>
+define void @add_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %vaddr, <4 x i32> %b) #0 {
+ %vec = load <4 x i32>, <4 x i32> addrspace(1)* %vaddr
+ %add = add <4 x i32> %vec, %b
+ store <4 x i32> %add, <4 x i32> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'add_i64'
+; CHECK: estimated cost of 2 for {{.*}} add i64
+define void @add_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %vaddr, i64 %b) #0 {
+ %vec = load i64, i64 addrspace(1)* %vaddr
+ %add = add i64 %vec, %b
+ store i64 %add, i64 addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'add_v2i64'
+; CHECK: estimated cost of 4 for {{.*}} add <2 x i64>
+define void @add_v2i64(<2 x i64> addrspace(1)* %out, <2 x i64> addrspace(1)* %vaddr, <2 x i64> %b) #0 {
+ %vec = load <2 x i64>, <2 x i64> addrspace(1)* %vaddr
+ %add = add <2 x i64> %vec, %b
+ store <2 x i64> %add, <2 x i64> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'add_v3i64'
+; CHECK: estimated cost of 6 for {{.*}} add <3 x i64>
+define void @add_v3i64(<3 x i64> addrspace(1)* %out, <3 x i64> addrspace(1)* %vaddr, <3 x i64> %b) #0 {
+ %vec = load <3 x i64>, <3 x i64> addrspace(1)* %vaddr
+ %add = add <3 x i64> %vec, %b
+ store <3 x i64> %add, <3 x i64> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'add_v4i64'
+; CHECK: estimated cost of 8 for {{.*}} add <4 x i64>
+define void @add_v4i64(<4 x i64> addrspace(1)* %out, <4 x i64> addrspace(1)* %vaddr, <4 x i64> %b) #0 {
+ %vec = load <4 x i64>, <4 x i64> addrspace(1)* %vaddr
+ %add = add <4 x i64> %vec, %b
+ store <4 x i64> %add, <4 x i64> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'add_v16i64'
+; CHECK: estimated cost of 32 for {{.*}} add <16 x i64>
+define void @add_v16i64(<16 x i64> addrspace(1)* %out, <16 x i64> addrspace(1)* %vaddr, <16 x i64> %b) #0 {
+ %vec = load <16 x i64>, <16 x i64> addrspace(1)* %vaddr
+ %add = add <16 x i64> %vec, %b
+ store <16 x i64> %add, <16 x i64> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'add_i16'
+; CHECK: estimated cost of 1 for {{.*}} add i16
+define void @add_i16(i16 addrspace(1)* %out, i16 addrspace(1)* %vaddr, i16 %b) #0 {
+ %vec = load i16, i16 addrspace(1)* %vaddr
+ %add = add i16 %vec, %b
+ store i16 %add, i16 addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'add_v2i16'
+; CHECK: estimated cost of 2 for {{.*}} add <2 x i16>
+define void @add_v2i16(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %vaddr, <2 x i16> %b) #0 {
+ %vec = load <2 x i16>, <2 x i16> addrspace(1)* %vaddr
+ %add = add <2 x i16> %vec, %b
+ store <2 x i16> %add, <2 x i16> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'sub_i32'
+; CHECK: estimated cost of 1 for {{.*}} sub i32
+define void @sub_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %vaddr, i32 %b) #0 {
+ %vec = load i32, i32 addrspace(1)* %vaddr
+ %sub = sub i32 %vec, %b
+ store i32 %sub, i32 addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'sub_i64'
+; CHECK: estimated cost of 2 for {{.*}} sub i64
+define void @sub_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %vaddr, i64 %b) #0 {
+ %vec = load i64, i64 addrspace(1)* %vaddr
+ %sub = sub i64 %vec, %b
+ store i64 %sub, i64 addrspace(1)* %out
+ ret void
+}
+; CHECK: 'sub_i16'
+; CHECK: estimated cost of 1 for {{.*}} sub i16
+define void @sub_i16(i16 addrspace(1)* %out, i16 addrspace(1)* %vaddr, i16 %b) #0 {
+ %vec = load i16, i16 addrspace(1)* %vaddr
+ %sub = sub i16 %vec, %b
+ store i16 %sub, i16 addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'sub_v2i16'
+; CHECK: estimated cost of 2 for {{.*}} sub <2 x i16>
+define void @sub_v2i16(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %vaddr, <2 x i16> %b) #0 {
+ %vec = load <2 x i16>, <2 x i16> addrspace(1)* %vaddr
+ %sub = sub <2 x i16> %vec, %b
+ store <2 x i16> %sub, <2 x i16> addrspace(1)* %out
+ ret void
+}
+
+attributes #0 = { nounwind }
diff --git a/test/Analysis/CostModel/AMDGPU/addrspacecast.ll b/test/Analysis/CostModel/AMDGPU/addrspacecast.ll
new file mode 100644
index 0000000000000..1f6cb85a789de
--- /dev/null
+++ b/test/Analysis/CostModel/AMDGPU/addrspacecast.ll
@@ -0,0 +1,45 @@
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa -mcpu=kaveri < %s | FileCheck %s
+
+; CHECK: 'addrspacecast_global_to_flat'
+; CHECK: estimated cost of 0 for {{.*}} addrspacecast i8 addrspace(1)* %ptr to i8 addrspace(4)*
+define i8 addrspace(4)* @addrspacecast_global_to_flat(i8 addrspace(1)* %ptr) #0 {
+ %cast = addrspacecast i8 addrspace(1)* %ptr to i8 addrspace(4)*
+ ret i8 addrspace(4)* %cast
+}
+
+; CHECK: 'addrspacecast_global_to_flat_v2'
+; CHECK: estimated cost of 0 for {{.*}} addrspacecast <2 x i8 addrspace(1)*> %ptr to <2 x i8 addrspace(4)*>
+define <2 x i8 addrspace(4)*> @addrspacecast_global_to_flat_v2(<2 x i8 addrspace(1)*> %ptr) #0 {
+ %cast = addrspacecast <2 x i8 addrspace(1)*> %ptr to <2 x i8 addrspace(4)*>
+ ret <2 x i8 addrspace(4)*> %cast
+}
+
+; CHECK: 'addrspacecast_global_to_flat_v32'
+; CHECK: estimated cost of 0 for {{.*}} addrspacecast <32 x i8 addrspace(1)*> %ptr to <32 x i8 addrspace(4)*>
+define <32 x i8 addrspace(4)*> @addrspacecast_global_to_flat_v32(<32 x i8 addrspace(1)*> %ptr) #0 {
+ %cast = addrspacecast <32 x i8 addrspace(1)*> %ptr to <32 x i8 addrspace(4)*>
+ ret <32 x i8 addrspace(4)*> %cast
+}
+
+; CHECK: 'addrspacecast_local_to_flat'
+; CHECK: estimated cost of 1 for {{.*}} addrspacecast i8 addrspace(3)* %ptr to i8 addrspace(4)*
+define i8 addrspace(4)* @addrspacecast_local_to_flat(i8 addrspace(3)* %ptr) #0 {
+ %cast = addrspacecast i8 addrspace(3)* %ptr to i8 addrspace(4)*
+ ret i8 addrspace(4)* %cast
+}
+
+; CHECK: 'addrspacecast_local_to_flat_v2'
+; CHECK: estimated cost of 2 for {{.*}} addrspacecast <2 x i8 addrspace(3)*> %ptr to <2 x i8 addrspace(4)*>
+define <2 x i8 addrspace(4)*> @addrspacecast_local_to_flat_v2(<2 x i8 addrspace(3)*> %ptr) #0 {
+ %cast = addrspacecast <2 x i8 addrspace(3)*> %ptr to <2 x i8 addrspace(4)*>
+ ret <2 x i8 addrspace(4)*> %cast
+}
+
+; CHECK: 'addrspacecast_local_to_flat_v32'
+; CHECK: estimated cost of 32 for {{.*}} addrspacecast <32 x i8 addrspace(3)*> %ptr to <32 x i8 addrspace(4)*>
+define <32 x i8 addrspace(4)*> @addrspacecast_local_to_flat_v32(<32 x i8 addrspace(3)*> %ptr) #0 {
+ %cast = addrspacecast <32 x i8 addrspace(3)*> %ptr to <32 x i8 addrspace(4)*>
+ ret <32 x i8 addrspace(4)*> %cast
+}
+
+attributes #0 = { nounwind readnone }
diff --git a/test/Analysis/CostModel/AMDGPU/bit-ops.ll b/test/Analysis/CostModel/AMDGPU/bit-ops.ll
new file mode 100644
index 0000000000000..a809dbd77bbf8
--- /dev/null
+++ b/test/Analysis/CostModel/AMDGPU/bit-ops.ll
@@ -0,0 +1,59 @@
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa < %s | FileCheck %s
+
+; CHECK: 'or_i32'
+; CHECK: estimated cost of 1 for {{.*}} or i32
+define void @or_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %vaddr, i32 %b) #0 {
+ %vec = load i32, i32 addrspace(1)* %vaddr
+ %or = or i32 %vec, %b
+ store i32 %or, i32 addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'or_i64'
+; CHECK: estimated cost of 2 for {{.*}} or i64
+define void @or_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %vaddr, i64 %b) #0 {
+ %vec = load i64, i64 addrspace(1)* %vaddr
+ %or = or i64 %vec, %b
+ store i64 %or, i64 addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'xor_i32'
+; CHECK: estimated cost of 1 for {{.*}} xor i32
+define void @xor_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %vaddr, i32 %b) #0 {
+ %vec = load i32, i32 addrspace(1)* %vaddr
+ %or = xor i32 %vec, %b
+ store i32 %or, i32 addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'xor_i64'
+; CHECK: estimated cost of 2 for {{.*}} xor i64
+define void @xor_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %vaddr, i64 %b) #0 {
+ %vec = load i64, i64 addrspace(1)* %vaddr
+ %or = xor i64 %vec, %b
+ store i64 %or, i64 addrspace(1)* %out
+ ret void
+}
+
+
+; CHECK: 'and_i32'
+; CHECK: estimated cost of 1 for {{.*}} and i32
+define void @and_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %vaddr, i32 %b) #0 {
+ %vec = load i32, i32 addrspace(1)* %vaddr
+ %or = and i32 %vec, %b
+ store i32 %or, i32 addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'and_i64'
+; CHECK: estimated cost of 2 for {{.*}} and i64
+define void @and_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %vaddr, i64 %b) #0 {
+ %vec = load i64, i64 addrspace(1)* %vaddr
+ %or = and i64 %vec, %b
+ store i64 %or, i64 addrspace(1)* %out
+ ret void
+}
+
+
+attributes #0 = { nounwind }
diff --git a/test/Analysis/CostModel/AMDGPU/fabs.ll b/test/Analysis/CostModel/AMDGPU/fabs.ll
new file mode 100644
index 0000000000000..9c551ec8afe51
--- /dev/null
+++ b/test/Analysis/CostModel/AMDGPU/fabs.ll
@@ -0,0 +1,97 @@
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa < %s | FileCheck %s
+
+; CHECK: 'fabs_f32'
+; CHECK: estimated cost of 0 for {{.*}} call float @llvm.fabs.f32
+define void @fabs_f32(float addrspace(1)* %out, float addrspace(1)* %vaddr) #0 {
+ %vec = load float, float addrspace(1)* %vaddr
+ %fabs = call float @llvm.fabs.f32(float %vec) #1
+ store float %fabs, float addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'fabs_v2f32'
+; CHECK: estimated cost of 0 for {{.*}} call <2 x float> @llvm.fabs.v2f32
+define void @fabs_v2f32(<2 x float> addrspace(1)* %out, <2 x float> addrspace(1)* %vaddr) #0 {
+ %vec = load <2 x float>, <2 x float> addrspace(1)* %vaddr
+ %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %vec) #1
+ store <2 x float> %fabs, <2 x float> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'fabs_v3f32'
+; CHECK: estimated cost of 0 for {{.*}} call <3 x float> @llvm.fabs.v3f32
+define void @fabs_v3f32(<3 x float> addrspace(1)* %out, <3 x float> addrspace(1)* %vaddr) #0 {
+ %vec = load <3 x float>, <3 x float> addrspace(1)* %vaddr
+ %fabs = call <3 x float> @llvm.fabs.v3f32(<3 x float> %vec) #1
+ store <3 x float> %fabs, <3 x float> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'fabs_f64'
+; CHECK: estimated cost of 0 for {{.*}} call double @llvm.fabs.f64
+define void @fabs_f64(double addrspace(1)* %out, double addrspace(1)* %vaddr) #0 {
+ %vec = load double, double addrspace(1)* %vaddr
+ %fabs = call double @llvm.fabs.f64(double %vec) #1
+ store double %fabs, double addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'fabs_v2f64'
+; CHECK: estimated cost of 0 for {{.*}} call <2 x double> @llvm.fabs.v2f64
+define void @fabs_v2f64(<2 x double> addrspace(1)* %out, <2 x double> addrspace(1)* %vaddr) #0 {
+ %vec = load <2 x double>, <2 x double> addrspace(1)* %vaddr
+ %fabs = call <2 x double> @llvm.fabs.v2f64(<2 x double> %vec) #1
+ store <2 x double> %fabs, <2 x double> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'fabs_v3f64'
+; CHECK: estimated cost of 0 for {{.*}} call <3 x double> @llvm.fabs.v3f64
+define void @fabs_v3f64(<3 x double> addrspace(1)* %out, <3 x double> addrspace(1)* %vaddr) #0 {
+ %vec = load <3 x double>, <3 x double> addrspace(1)* %vaddr
+ %fabs = call <3 x double> @llvm.fabs.v3f64(<3 x double> %vec) #1
+ store <3 x double> %fabs, <3 x double> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'fabs_f16'
+; CHECK: estimated cost of 0 for {{.*}} call half @llvm.fabs.f16
+define void @fabs_f16(half addrspace(1)* %out, half addrspace(1)* %vaddr) #0 {
+ %vec = load half, half addrspace(1)* %vaddr
+ %fabs = call half @llvm.fabs.f16(half %vec) #1
+ store half %fabs, half addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'fabs_v2f16'
+; CHECK: estimated cost of 0 for {{.*}} call <2 x half> @llvm.fabs.v2f16
+define void @fabs_v2f16(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %vaddr) #0 {
+ %vec = load <2 x half>, <2 x half> addrspace(1)* %vaddr
+ %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %vec) #1
+ store <2 x half> %fabs, <2 x half> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'fabs_v3f16'
+; CHECK: estimated cost of 0 for {{.*}} call <3 x half> @llvm.fabs.v3f16
+define void @fabs_v3f16(<3 x half> addrspace(1)* %out, <3 x half> addrspace(1)* %vaddr) #0 {
+ %vec = load <3 x half>, <3 x half> addrspace(1)* %vaddr
+ %fabs = call <3 x half> @llvm.fabs.v3f16(<3 x half> %vec) #1
+ store <3 x half> %fabs, <3 x half> addrspace(1)* %out
+ ret void
+}
+
+declare float @llvm.fabs.f32(float) #1
+declare <2 x float> @llvm.fabs.v2f32(<2 x float>) #1
+declare <3 x float> @llvm.fabs.v3f32(<3 x float>) #1
+
+declare double @llvm.fabs.f64(double) #1
+declare <2 x double> @llvm.fabs.v2f64(<2 x double>) #1
+declare <3 x double> @llvm.fabs.v3f64(<3 x double>) #1
+
+declare half @llvm.fabs.f16(half) #1
+declare <2 x half> @llvm.fabs.v2f16(<2 x half>) #1
+declare <3 x half> @llvm.fabs.v3f16(<3 x half>) #1
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone }
diff --git a/test/Analysis/CostModel/AMDGPU/fadd.ll b/test/Analysis/CostModel/AMDGPU/fadd.ll
new file mode 100644
index 0000000000000..00e91bd6223aa
--- /dev/null
+++ b/test/Analysis/CostModel/AMDGPU/fadd.ll
@@ -0,0 +1,88 @@
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa -mattr=+half-rate-64-ops < %s | FileCheck -check-prefix=FASTF64 -check-prefix=ALL %s
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa -mattr=-half-rate-64-ops < %s | FileCheck -check-prefix=SLOWF64 -check-prefix=ALL %s
+
+; ALL: 'fadd_f32'
+; ALL: estimated cost of 1 for {{.*}} fadd float
+define void @fadd_f32(float addrspace(1)* %out, float addrspace(1)* %vaddr, float %b) #0 {
+ %vec = load float, float addrspace(1)* %vaddr
+ %add = fadd float %vec, %b
+ store float %add, float addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fadd_v2f32'
+; ALL: estimated cost of 2 for {{.*}} fadd <2 x float>
+define void @fadd_v2f32(<2 x float> addrspace(1)* %out, <2 x float> addrspace(1)* %vaddr, <2 x float> %b) #0 {
+ %vec = load <2 x float>, <2 x float> addrspace(1)* %vaddr
+ %add = fadd <2 x float> %vec, %b
+ store <2 x float> %add, <2 x float> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fadd_v3f32'
+; ALL: estimated cost of 3 for {{.*}} fadd <3 x float>
+define void @fadd_v3f32(<3 x float> addrspace(1)* %out, <3 x float> addrspace(1)* %vaddr, <3 x float> %b) #0 {
+ %vec = load <3 x float>, <3 x float> addrspace(1)* %vaddr
+ %add = fadd <3 x float> %vec, %b
+ store <3 x float> %add, <3 x float> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fadd_f64'
+; FASTF64: estimated cost of 2 for {{.*}} fadd double
+; SLOWF64: estimated cost of 3 for {{.*}} fadd double
+define void @fadd_f64(double addrspace(1)* %out, double addrspace(1)* %vaddr, double %b) #0 {
+ %vec = load double, double addrspace(1)* %vaddr
+ %add = fadd double %vec, %b
+ store double %add, double addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fadd_v2f64'
+; FASTF64: estimated cost of 4 for {{.*}} fadd <2 x double>
+; SLOWF64: estimated cost of 6 for {{.*}} fadd <2 x double>
+define void @fadd_v2f64(<2 x double> addrspace(1)* %out, <2 x double> addrspace(1)* %vaddr, <2 x double> %b) #0 {
+ %vec = load <2 x double>, <2 x double> addrspace(1)* %vaddr
+ %add = fadd <2 x double> %vec, %b
+ store <2 x double> %add, <2 x double> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fadd_v3f64'
+; FASTF64: estimated cost of 6 for {{.*}} fadd <3 x double>
+; SLOWF64: estimated cost of 9 for {{.*}} fadd <3 x double>
+define void @fadd_v3f64(<3 x double> addrspace(1)* %out, <3 x double> addrspace(1)* %vaddr, <3 x double> %b) #0 {
+ %vec = load <3 x double>, <3 x double> addrspace(1)* %vaddr
+ %add = fadd <3 x double> %vec, %b
+ store <3 x double> %add, <3 x double> addrspace(1)* %out
+ ret void
+}
+
+; ALL 'fadd_f16'
+; ALL estimated cost of 1 for {{.*}} fadd half
+define void @fadd_f16(half addrspace(1)* %out, half addrspace(1)* %vaddr, half %b) #0 {
+ %vec = load half, half addrspace(1)* %vaddr
+ %add = fadd half %vec, %b
+ store half %add, half addrspace(1)* %out
+ ret void
+}
+
+; ALL 'fadd_v2f16'
+; ALL estimated cost of 2 for {{.*}} fadd <2 x half>
+define void @fadd_v2f16(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %vaddr, <2 x half> %b) #0 {
+ %vec = load <2 x half>, <2 x half> addrspace(1)* %vaddr
+ %add = fadd <2 x half> %vec, %b
+ store <2 x half> %add, <2 x half> addrspace(1)* %out
+ ret void
+}
+
+; ALL 'fadd_v4f16'
+; ALL estimated cost of 4 for {{.*}} fadd <4 x half>
+define void @fadd_v4f16(<4 x half> addrspace(1)* %out, <4 x half> addrspace(1)* %vaddr, <4 x half> %b) #0 {
+ %vec = load <4 x half>, <4 x half> addrspace(1)* %vaddr
+ %add = fadd <4 x half> %vec, %b
+ store <4 x half> %add, <4 x half> addrspace(1)* %out
+ ret void
+}
+
+attributes #0 = { nounwind }
diff --git a/test/Analysis/CostModel/AMDGPU/fdiv.ll b/test/Analysis/CostModel/AMDGPU/fdiv.ll
new file mode 100644
index 0000000000000..3f374422ad9d1
--- /dev/null
+++ b/test/Analysis/CostModel/AMDGPU/fdiv.ll
@@ -0,0 +1,96 @@
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa -mcpu=hawaii -mattr=+half-rate-64-ops < %s | FileCheck -check-prefix=ALL -check-prefix=CIFASTF64 %s
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa -mcpu=kaveri -mattr=-half-rate-64-ops < %s | FileCheck -check-prefix=ALL -check-prefix=CISLOWF64 %s
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa -mcpu=tahiti -mattr=+half-rate-64-ops < %s | FileCheck -check-prefix=ALL -check-prefix=SIFASTF64 %s
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa -mcpu=verde -mattr=-half-rate-64-ops < %s | FileCheck -check-prefix=ALL -check-prefix=SISLOWF64 %s
+
+; CHECK: 'fdiv_f32'
+; ALL: estimated cost of 10 for {{.*}} fdiv float
+define void @fdiv_f32(float addrspace(1)* %out, float addrspace(1)* %vaddr, float %b) #0 {
+ %vec = load float, float addrspace(1)* %vaddr
+ %add = fdiv float %vec, %b
+ store float %add, float addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fdiv_v2f32'
+; ALL: estimated cost of 20 for {{.*}} fdiv <2 x float>
+define void @fdiv_v2f32(<2 x float> addrspace(1)* %out, <2 x float> addrspace(1)* %vaddr, <2 x float> %b) #0 {
+ %vec = load <2 x float>, <2 x float> addrspace(1)* %vaddr
+ %add = fdiv <2 x float> %vec, %b
+ store <2 x float> %add, <2 x float> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fdiv_v3f32'
+; ALL: estimated cost of 30 for {{.*}} fdiv <3 x float>
+define void @fdiv_v3f32(<3 x float> addrspace(1)* %out, <3 x float> addrspace(1)* %vaddr, <3 x float> %b) #0 {
+ %vec = load <3 x float>, <3 x float> addrspace(1)* %vaddr
+ %add = fdiv <3 x float> %vec, %b
+ store <3 x float> %add, <3 x float> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fdiv_f64'
+; CIFASTF64: estimated cost of 29 for {{.*}} fdiv double
+; CISLOWF64: estimated cost of 33 for {{.*}} fdiv double
+; SIFASTF64: estimated cost of 32 for {{.*}} fdiv double
+; SISLOWF64: estimated cost of 36 for {{.*}} fdiv double
+define void @fdiv_f64(double addrspace(1)* %out, double addrspace(1)* %vaddr, double %b) #0 {
+ %vec = load double, double addrspace(1)* %vaddr
+ %add = fdiv double %vec, %b
+ store double %add, double addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fdiv_v2f64'
+; CIFASTF64: estimated cost of 58 for {{.*}} fdiv <2 x double>
+; CISLOWF64: estimated cost of 66 for {{.*}} fdiv <2 x double>
+; SIFASTF64: estimated cost of 64 for {{.*}} fdiv <2 x double>
+; SISLOWF64: estimated cost of 72 for {{.*}} fdiv <2 x double>
+define void @fdiv_v2f64(<2 x double> addrspace(1)* %out, <2 x double> addrspace(1)* %vaddr, <2 x double> %b) #0 {
+ %vec = load <2 x double>, <2 x double> addrspace(1)* %vaddr
+ %add = fdiv <2 x double> %vec, %b
+ store <2 x double> %add, <2 x double> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fdiv_v3f64'
+; CIFASTF64: estimated cost of 87 for {{.*}} fdiv <3 x double>
+; CISLOWF64: estimated cost of 99 for {{.*}} fdiv <3 x double>
+; SIFASTF64: estimated cost of 96 for {{.*}} fdiv <3 x double>
+; SISLOWF64: estimated cost of 108 for {{.*}} fdiv <3 x double>
+define void @fdiv_v3f64(<3 x double> addrspace(1)* %out, <3 x double> addrspace(1)* %vaddr, <3 x double> %b) #0 {
+ %vec = load <3 x double>, <3 x double> addrspace(1)* %vaddr
+ %add = fdiv <3 x double> %vec, %b
+ store <3 x double> %add, <3 x double> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fdiv_f16'
+; ALL: estimated cost of 10 for {{.*}} fdiv half
+define void @fdiv_f16(half addrspace(1)* %out, half addrspace(1)* %vaddr, half %b) #0 {
+ %vec = load half, half addrspace(1)* %vaddr
+ %add = fdiv half %vec, %b
+ store half %add, half addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fdiv_v2f16'
+; ALL: estimated cost of 20 for {{.*}} fdiv <2 x half>
+define void @fdiv_v2f16(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %vaddr, <2 x half> %b) #0 {
+ %vec = load <2 x half>, <2 x half> addrspace(1)* %vaddr
+ %add = fdiv <2 x half> %vec, %b
+ store <2 x half> %add, <2 x half> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fdiv_v4f16'
+; ALL: estimated cost of 40 for {{.*}} fdiv <4 x half>
+define void @fdiv_v4f16(<4 x half> addrspace(1)* %out, <4 x half> addrspace(1)* %vaddr, <4 x half> %b) #0 {
+ %vec = load <4 x half>, <4 x half> addrspace(1)* %vaddr
+ %add = fdiv <4 x half> %vec, %b
+ store <4 x half> %add, <4 x half> addrspace(1)* %out
+ ret void
+}
+
+attributes #0 = { nounwind }
diff --git a/test/Analysis/CostModel/AMDGPU/fmul.ll b/test/Analysis/CostModel/AMDGPU/fmul.ll
new file mode 100644
index 0000000000000..6303bb7988c54
--- /dev/null
+++ b/test/Analysis/CostModel/AMDGPU/fmul.ll
@@ -0,0 +1,88 @@
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa -mattr=+half-rate-64-ops < %s | FileCheck -check-prefix=FASTF64 -check-prefix=ALL %s
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa -mattr=-half-rate-64-ops < %s | FileCheck -check-prefix=SLOWF64 -check-prefix=ALL %s
+
+; ALL: 'fmul_f32'
+; ALL: estimated cost of 1 for {{.*}} fmul float
+define void @fmul_f32(float addrspace(1)* %out, float addrspace(1)* %vaddr, float %b) #0 {
+ %vec = load float, float addrspace(1)* %vaddr
+ %add = fmul float %vec, %b
+ store float %add, float addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fmul_v2f32'
+; ALL: estimated cost of 2 for {{.*}} fmul <2 x float>
+define void @fmul_v2f32(<2 x float> addrspace(1)* %out, <2 x float> addrspace(1)* %vaddr, <2 x float> %b) #0 {
+ %vec = load <2 x float>, <2 x float> addrspace(1)* %vaddr
+ %add = fmul <2 x float> %vec, %b
+ store <2 x float> %add, <2 x float> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fmul_v3f32'
+; ALL: estimated cost of 3 for {{.*}} fmul <3 x float>
+define void @fmul_v3f32(<3 x float> addrspace(1)* %out, <3 x float> addrspace(1)* %vaddr, <3 x float> %b) #0 {
+ %vec = load <3 x float>, <3 x float> addrspace(1)* %vaddr
+ %add = fmul <3 x float> %vec, %b
+ store <3 x float> %add, <3 x float> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fmul_f64'
+; FASTF64: estimated cost of 2 for {{.*}} fmul double
+; SLOWF64: estimated cost of 3 for {{.*}} fmul double
+define void @fmul_f64(double addrspace(1)* %out, double addrspace(1)* %vaddr, double %b) #0 {
+ %vec = load double, double addrspace(1)* %vaddr
+ %add = fmul double %vec, %b
+ store double %add, double addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fmul_v2f64'
+; FASTF64: estimated cost of 4 for {{.*}} fmul <2 x double>
+; SLOWF64: estimated cost of 6 for {{.*}} fmul <2 x double>
+define void @fmul_v2f64(<2 x double> addrspace(1)* %out, <2 x double> addrspace(1)* %vaddr, <2 x double> %b) #0 {
+ %vec = load <2 x double>, <2 x double> addrspace(1)* %vaddr
+ %add = fmul <2 x double> %vec, %b
+ store <2 x double> %add, <2 x double> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fmul_v3f64'
+; FASTF64: estimated cost of 6 for {{.*}} fmul <3 x double>
+; SLOWF64: estimated cost of 9 for {{.*}} fmul <3 x double>
+define void @fmul_v3f64(<3 x double> addrspace(1)* %out, <3 x double> addrspace(1)* %vaddr, <3 x double> %b) #0 {
+ %vec = load <3 x double>, <3 x double> addrspace(1)* %vaddr
+ %add = fmul <3 x double> %vec, %b
+ store <3 x double> %add, <3 x double> addrspace(1)* %out
+ ret void
+}
+
+; ALL 'fmul_f16'
+; ALL estimated cost of 1 for {{.*}} fmul half
+define void @fmul_f16(half addrspace(1)* %out, half addrspace(1)* %vaddr, half %b) #0 {
+ %vec = load half, half addrspace(1)* %vaddr
+ %add = fmul half %vec, %b
+ store half %add, half addrspace(1)* %out
+ ret void
+}
+
+; ALL 'fmul_v2f16'
+; ALL estimated cost of 2 for {{.*}} fmul <2 x half>
+define void @fmul_v2f16(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %vaddr, <2 x half> %b) #0 {
+ %vec = load <2 x half>, <2 x half> addrspace(1)* %vaddr
+ %add = fmul <2 x half> %vec, %b
+ store <2 x half> %add, <2 x half> addrspace(1)* %out
+ ret void
+}
+
+; ALL 'fmul_v4f16'
+; ALL estimated cost of 4 for {{.*}} fmul <4 x half>
+define void @fmul_v4f16(<4 x half> addrspace(1)* %out, <4 x half> addrspace(1)* %vaddr, <4 x half> %b) #0 {
+ %vec = load <4 x half>, <4 x half> addrspace(1)* %vaddr
+ %add = fmul <4 x half> %vec, %b
+ store <4 x half> %add, <4 x half> addrspace(1)* %out
+ ret void
+}
+
+attributes #0 = { nounwind }
diff --git a/test/Analysis/CostModel/AMDGPU/fsub.ll b/test/Analysis/CostModel/AMDGPU/fsub.ll
new file mode 100644
index 0000000000000..e0850be9867ea
--- /dev/null
+++ b/test/Analysis/CostModel/AMDGPU/fsub.ll
@@ -0,0 +1,86 @@
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa -mattr=+half-rate-64-ops < %s | FileCheck -check-prefix=FASTF64 -check-prefix=ALL %s
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa -mattr=-half-rate-64-ops < %s | FileCheck -check-prefix=SLOWF64 -check-prefix=ALL %s
+
+; ALL: 'fsub_f32'
+; ALL: estimated cost of 1 for {{.*}} fsub float
+define void @fsub_f32(float addrspace(1)* %out, float addrspace(1)* %vaddr, float %b) #0 {
+ %vec = load float, float addrspace(1)* %vaddr
+ %add = fsub float %vec, %b
+ store float %add, float addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fsub_v2f32'
+; ALL: estimated cost of 2 for {{.*}} fsub <2 x float>
+define void @fsub_v2f32(<2 x float> addrspace(1)* %out, <2 x float> addrspace(1)* %vaddr, <2 x float> %b) #0 {
+ %vec = load <2 x float>, <2 x float> addrspace(1)* %vaddr
+ %add = fsub <2 x float> %vec, %b
+ store <2 x float> %add, <2 x float> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fsub_v3f32'
+; ALL: estimated cost of 3 for {{.*}} fsub <3 x float>
+define void @fsub_v3f32(<3 x float> addrspace(1)* %out, <3 x float> addrspace(1)* %vaddr, <3 x float> %b) #0 {
+ %vec = load <3 x float>, <3 x float> addrspace(1)* %vaddr
+ %add = fsub <3 x float> %vec, %b
+ store <3 x float> %add, <3 x float> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fsub_f64'
+; FASTF64: estimated cost of 2 for {{.*}} fsub double
+; SLOWF64: estimated cost of 3 for {{.*}} fsub double
+define void @fsub_f64(double addrspace(1)* %out, double addrspace(1)* %vaddr, double %b) #0 {
+ %vec = load double, double addrspace(1)* %vaddr
+ %add = fsub double %vec, %b
+ store double %add, double addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fsub_v2f64'
+; FASTF64: estimated cost of 4 for {{.*}} fsub <2 x double>
+; SLOWF64: estimated cost of 6 for {{.*}} fsub <2 x double>
+define void @fsub_v2f64(<2 x double> addrspace(1)* %out, <2 x double> addrspace(1)* %vaddr, <2 x double> %b) #0 {
+ %vec = load <2 x double>, <2 x double> addrspace(1)* %vaddr
+ %add = fsub <2 x double> %vec, %b
+ store <2 x double> %add, <2 x double> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fsub_v3f64'
+; FASTF64: estimated cost of 6 for {{.*}} fsub <3 x double>
+; SLOWF64: estimated cost of 9 for {{.*}} fsub <3 x double>
+define void @fsub_v3f64(<3 x double> addrspace(1)* %out, <3 x double> addrspace(1)* %vaddr, <3 x double> %b) #0 {
+ %vec = load <3 x double>, <3 x double> addrspace(1)* %vaddr
+ %add = fsub <3 x double> %vec, %b
+ store <3 x double> %add, <3 x double> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fsub_f16'
+; ALL: estimated cost of 1 for {{.*}} fsub half
+define void @fsub_f16(half addrspace(1)* %out, half addrspace(1)* %vaddr, half %b) #0 {
+ %vec = load half, half addrspace(1)* %vaddr
+ %add = fsub half %vec, %b
+ store half %add, half addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fsub_v2f16'
+; ALL: estimated cost of 2 for {{.*}} fsub <2 x half>
+define void @fsub_v2f16(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %vaddr, <2 x half> %b) #0 {
+ %vec = load <2 x half>, <2 x half> addrspace(1)* %vaddr
+ %add = fsub <2 x half> %vec, %b
+ store <2 x half> %add, <2 x half> addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'fsub_v4f16'
+; ALL: estimated cost of 4 for {{.*}} fsub <4 x half>
+define void @fsub_v4f16(<4 x half> addrspace(1)* %out, <4 x half> addrspace(1)* %vaddr, <4 x half> %b) #0 {
+ %vec = load <4 x half>, <4 x half> addrspace(1)* %vaddr
+ %add = fsub <4 x half> %vec, %b
+ store <4 x half> %add, <4 x half> addrspace(1)* %out
+ ret void
+}
diff --git a/test/Analysis/CostModel/AMDGPU/insertelement.ll b/test/Analysis/CostModel/AMDGPU/insertelement.ll
new file mode 100644
index 0000000000000..1765afe3169e1
--- /dev/null
+++ b/test/Analysis/CostModel/AMDGPU/insertelement.ll
@@ -0,0 +1,37 @@
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa < %s | FileCheck %s
+
+; CHECK: 'insertelement_v2i32'
+; CHECK: estimated cost of 0 for {{.*}} insertelement <2 x i32>
+define void @insertelement_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> addrspace(1)* %vaddr) {
+ %vec = load <2 x i32>, <2 x i32> addrspace(1)* %vaddr
+ %insert = insertelement <2 x i32> %vec, i32 1, i32 123
+ store <2 x i32> %insert, <2 x i32> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'insertelement_v2i64'
+; CHECK: estimated cost of 0 for {{.*}} insertelement <2 x i64>
+define void @insertelement_v2i64(<2 x i64> addrspace(1)* %out, <2 x i64> addrspace(1)* %vaddr) {
+ %vec = load <2 x i64>, <2 x i64> addrspace(1)* %vaddr
+ %insert = insertelement <2 x i64> %vec, i64 1, i64 123
+ store <2 x i64> %insert, <2 x i64> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'insertelement_v2i16'
+; CHECK: estimated cost of 0 for {{.*}} insertelement <2 x i16>
+define void @insertelement_v2i16(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %vaddr) {
+ %vec = load <2 x i16>, <2 x i16> addrspace(1)* %vaddr
+ %insert = insertelement <2 x i16> %vec, i16 1, i16 123
+ store <2 x i16> %insert, <2 x i16> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'insertelement_v2i8'
+; CHECK: estimated cost of 0 for {{.*}} insertelement <2 x i8>
+define void @insertelement_v2i8(<2 x i8> addrspace(1)* %out, <2 x i8> addrspace(1)* %vaddr) {
+ %vec = load <2 x i8>, <2 x i8> addrspace(1)* %vaddr
+ %insert = insertelement <2 x i8> %vec, i8 1, i8 123
+ store <2 x i8> %insert, <2 x i8> addrspace(1)* %out
+ ret void
+}
diff --git a/test/Analysis/CostModel/AMDGPU/mul.ll b/test/Analysis/CostModel/AMDGPU/mul.ll
new file mode 100644
index 0000000000000..cbc755a6e6a97
--- /dev/null
+++ b/test/Analysis/CostModel/AMDGPU/mul.ll
@@ -0,0 +1,85 @@
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa < %s | FileCheck %s
+
+; CHECK: 'mul_i32'
+; CHECK: estimated cost of 3 for {{.*}} mul i32
+define void @mul_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %vaddr, i32 %b) #0 {
+ %vec = load i32, i32 addrspace(1)* %vaddr
+ %mul = mul i32 %vec, %b
+ store i32 %mul, i32 addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'mul_v2i32'
+; CHECK: estimated cost of 6 for {{.*}} mul <2 x i32>
+define void @mul_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> addrspace(1)* %vaddr, <2 x i32> %b) #0 {
+ %vec = load <2 x i32>, <2 x i32> addrspace(1)* %vaddr
+ %mul = mul <2 x i32> %vec, %b
+ store <2 x i32> %mul, <2 x i32> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'mul_v3i32'
+; CHECK: estimated cost of 9 for {{.*}} mul <3 x i32>
+define void @mul_v3i32(<3 x i32> addrspace(1)* %out, <3 x i32> addrspace(1)* %vaddr, <3 x i32> %b) #0 {
+ %vec = load <3 x i32>, <3 x i32> addrspace(1)* %vaddr
+ %mul = mul <3 x i32> %vec, %b
+ store <3 x i32> %mul, <3 x i32> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'mul_v4i32'
+; CHECK: estimated cost of 12 for {{.*}} mul <4 x i32>
+define void @mul_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %vaddr, <4 x i32> %b) #0 {
+ %vec = load <4 x i32>, <4 x i32> addrspace(1)* %vaddr
+ %mul = mul <4 x i32> %vec, %b
+ store <4 x i32> %mul, <4 x i32> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'mul_i64'
+; CHECK: estimated cost of 16 for {{.*}} mul i64
+define void @mul_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %vaddr, i64 %b) #0 {
+ %vec = load i64, i64 addrspace(1)* %vaddr
+ %mul = mul i64 %vec, %b
+ store i64 %mul, i64 addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'mul_v2i64'
+; CHECK: estimated cost of 32 for {{.*}} mul <2 x i64>
+define void @mul_v2i64(<2 x i64> addrspace(1)* %out, <2 x i64> addrspace(1)* %vaddr, <2 x i64> %b) #0 {
+ %vec = load <2 x i64>, <2 x i64> addrspace(1)* %vaddr
+ %mul = mul <2 x i64> %vec, %b
+ store <2 x i64> %mul, <2 x i64> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'mul_v3i64'
+; CHECK: estimated cost of 48 for {{.*}} mul <3 x i64>
+define void @mul_v3i64(<3 x i64> addrspace(1)* %out, <3 x i64> addrspace(1)* %vaddr, <3 x i64> %b) #0 {
+ %vec = load <3 x i64>, <3 x i64> addrspace(1)* %vaddr
+ %mul = mul <3 x i64> %vec, %b
+ store <3 x i64> %mul, <3 x i64> addrspace(1)* %out
+ ret void
+}
+
+; CHECK: 'mul_v4i64'
+; CHECK: estimated cost of 64 for {{.*}} mul <4 x i64>
+define void @mul_v4i64(<4 x i64> addrspace(1)* %out, <4 x i64> addrspace(1)* %vaddr, <4 x i64> %b) #0 {
+ %vec = load <4 x i64>, <4 x i64> addrspace(1)* %vaddr
+ %mul = mul <4 x i64> %vec, %b
+ store <4 x i64> %mul, <4 x i64> addrspace(1)* %out
+ ret void
+}
+
+
+; CHECK: 'mul_v8i64'
+; CHECK: estimated cost of 128 for {{.*}} mul <8 x i64>
+define void @mul_v8i64(<8 x i64> addrspace(1)* %out, <8 x i64> addrspace(1)* %vaddr, <8 x i64> %b) #0 {
+ %vec = load <8 x i64>, <8 x i64> addrspace(1)* %vaddr
+ %mul = mul <8 x i64> %vec, %b
+ store <8 x i64> %mul, <8 x i64> addrspace(1)* %out
+ ret void
+}
+
+attributes #0 = { nounwind }
diff --git a/test/Analysis/CostModel/AMDGPU/shifts.ll b/test/Analysis/CostModel/AMDGPU/shifts.ll
new file mode 100644
index 0000000000000..003aed7b2fc8e
--- /dev/null
+++ b/test/Analysis/CostModel/AMDGPU/shifts.ll
@@ -0,0 +1,61 @@
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa -mattr=+half-rate-64-ops < %s | FileCheck -check-prefix=ALL -check-prefix=FAST64 %s
+; RUN: opt -cost-model -analyze -mtriple=amdgcn-unknown-amdhsa -mattr=-half-rate-64-ops < %s | FileCheck -check-prefix=ALL -check-prefix=SLOW64 %s
+
+; ALL: 'shl_i32'
+; ALL: estimated cost of 1 for {{.*}} shl i32
+define void @shl_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %vaddr, i32 %b) #0 {
+ %vec = load i32, i32 addrspace(1)* %vaddr
+ %or = shl i32 %vec, %b
+ store i32 %or, i32 addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'shl_i64'
+; FAST64: estimated cost of 2 for {{.*}} shl i64
+; SLOW64: estimated cost of 3 for {{.*}} shl i64
+define void @shl_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %vaddr, i64 %b) #0 {
+ %vec = load i64, i64 addrspace(1)* %vaddr
+ %or = shl i64 %vec, %b
+ store i64 %or, i64 addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'lshr_i32'
+; ALL: estimated cost of 1 for {{.*}} lshr i32
+define void @lshr_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %vaddr, i32 %b) #0 {
+ %vec = load i32, i32 addrspace(1)* %vaddr
+ %or = lshr i32 %vec, %b
+ store i32 %or, i32 addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'lshr_i64'
+; FAST64: estimated cost of 2 for {{.*}} lshr i64
+; SLOW64: estimated cost of 3 for {{.*}} lshr i64
+define void @lshr_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %vaddr, i64 %b) #0 {
+ %vec = load i64, i64 addrspace(1)* %vaddr
+ %or = lshr i64 %vec, %b
+ store i64 %or, i64 addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'ashr_i32'
+; ALL: estimated cost of 1 for {{.*}} ashr i32
+define void @ashr_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %vaddr, i32 %b) #0 {
+ %vec = load i32, i32 addrspace(1)* %vaddr
+ %or = ashr i32 %vec, %b
+ store i32 %or, i32 addrspace(1)* %out
+ ret void
+}
+
+; ALL: 'ashr_i64'
+; FAST64: estimated cost of 2 for {{.*}} ashr i64
+; SLOW64: estimated cost of 3 for {{.*}} ashr i64
+define void @ashr_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %vaddr, i64 %b) #0 {
+ %vec = load i64, i64 addrspace(1)* %vaddr
+ %or = ashr i64 %vec, %b
+ store i64 %or, i64 addrspace(1)* %out
+ ret void
+}
+
+attributes #0 = { nounwind }
diff --git a/test/Analysis/CostModel/ARM/cast.ll b/test/Analysis/CostModel/ARM/cast.ll
index 21e2928220998..72308834c5359 100644
--- a/test/Analysis/CostModel/ARM/cast.ll
+++ b/test/Analysis/CostModel/ARM/cast.ll
@@ -264,39 +264,39 @@ define i32 @casts() {
%r116 = fptoui <4 x float> undef to <4 x i32>
; CHECK: Found an estimated cost of 1 for instruction: %r117 = fptosi <4 x float> undef to <4 x i32>
%r117 = fptosi <4 x float> undef to <4 x i32>
- ; CHECK: Found an estimated cost of 64 for instruction: %r118 = fptoui <4 x float> undef to <4 x i64>
+ ; CHECK: Found an estimated cost of 65 for instruction: %r118 = fptoui <4 x float> undef to <4 x i64>
%r118 = fptoui <4 x float> undef to <4 x i64>
- ; CHECK: Found an estimated cost of 64 for instruction: %r119 = fptosi <4 x float> undef to <4 x i64>
+ ; CHECK: Found an estimated cost of 65 for instruction: %r119 = fptosi <4 x float> undef to <4 x i64>
%r119 = fptosi <4 x float> undef to <4 x i64>
- ; CHECK: Found an estimated cost of 32 for instruction: %r120 = fptoui <4 x double> undef to <4 x i1>
+ ; CHECK: Found an estimated cost of 33 for instruction: %r120 = fptoui <4 x double> undef to <4 x i1>
%r120 = fptoui <4 x double> undef to <4 x i1>
- ; CHECK: Found an estimated cost of 32 for instruction: %r121 = fptosi <4 x double> undef to <4 x i1>
+ ; CHECK: Found an estimated cost of 33 for instruction: %r121 = fptosi <4 x double> undef to <4 x i1>
%r121 = fptosi <4 x double> undef to <4 x i1>
- ; CHECK: Found an estimated cost of 32 for instruction: %r122 = fptoui <4 x double> undef to <4 x i8>
+ ; CHECK: Found an estimated cost of 33 for instruction: %r122 = fptoui <4 x double> undef to <4 x i8>
%r122 = fptoui <4 x double> undef to <4 x i8>
- ; CHECK: Found an estimated cost of 32 for instruction: %r123 = fptosi <4 x double> undef to <4 x i8>
+ ; CHECK: Found an estimated cost of 33 for instruction: %r123 = fptosi <4 x double> undef to <4 x i8>
%r123 = fptosi <4 x double> undef to <4 x i8>
- ; CHECK: Found an estimated cost of 32 for instruction: %r124 = fptoui <4 x double> undef to <4 x i16>
+ ; CHECK: Found an estimated cost of 33 for instruction: %r124 = fptoui <4 x double> undef to <4 x i16>
%r124 = fptoui <4 x double> undef to <4 x i16>
- ; CHECK: Found an estimated cost of 32 for instruction: %r125 = fptosi <4 x double> undef to <4 x i16>
+ ; CHECK: Found an estimated cost of 33 for instruction: %r125 = fptosi <4 x double> undef to <4 x i16>
%r125 = fptosi <4 x double> undef to <4 x i16>
- ; CHECK: Found an estimated cost of 32 for instruction: %r126 = fptoui <4 x double> undef to <4 x i32>
+ ; CHECK: Found an estimated cost of 5 for instruction: %r126 = fptoui <4 x double> undef to <4 x i32>
%r126 = fptoui <4 x double> undef to <4 x i32>
- ; CHECK: Found an estimated cost of 32 for instruction: %r127 = fptosi <4 x double> undef to <4 x i32>
+ ; CHECK: Found an estimated cost of 5 for instruction: %r127 = fptosi <4 x double> undef to <4 x i32>
%r127 = fptosi <4 x double> undef to <4 x i32>
- ; CHECK: Found an estimated cost of 64 for instruction: %r128 = fptoui <4 x double> undef to <4 x i64>
+ ; CHECK: Found an estimated cost of 65 for instruction: %r128 = fptoui <4 x double> undef to <4 x i64>
%r128 = fptoui <4 x double> undef to <4 x i64>
- ; CHECK: Found an estimated cost of 64 for instruction: %r129 = fptosi <4 x double> undef to <4 x i64>
+ ; CHECK: Found an estimated cost of 65 for instruction: %r129 = fptosi <4 x double> undef to <4 x i64>
%r129 = fptosi <4 x double> undef to <4 x i64>
- ; CHECK: Found an estimated cost of 64 for instruction: %r130 = fptoui <8 x float> undef to <8 x i1>
+ ; CHECK: Found an estimated cost of 65 for instruction: %r130 = fptoui <8 x float> undef to <8 x i1>
%r130 = fptoui <8 x float> undef to <8 x i1>
- ; CHECK: Found an estimated cost of 64 for instruction: %r131 = fptosi <8 x float> undef to <8 x i1>
+ ; CHECK: Found an estimated cost of 65 for instruction: %r131 = fptosi <8 x float> undef to <8 x i1>
%r131 = fptosi <8 x float> undef to <8 x i1>
- ; CHECK: Found an estimated cost of 64 for instruction: %r132 = fptoui <8 x float> undef to <8 x i8>
+ ; CHECK: Found an estimated cost of 7 for instruction: %r132 = fptoui <8 x float> undef to <8 x i8>
%r132 = fptoui <8 x float> undef to <8 x i8>
- ; CHECK: Found an estimated cost of 64 for instruction: %r133 = fptosi <8 x float> undef to <8 x i8>
+ ; CHECK: Found an estimated cost of 7 for instruction: %r133 = fptosi <8 x float> undef to <8 x i8>
%r133 = fptosi <8 x float> undef to <8 x i8>
; CHECK: Found an estimated cost of 4 for instruction: %r134 = fptoui <8 x float> undef to <8 x i16>
%r134 = fptoui <8 x float> undef to <8 x i16>
@@ -306,39 +306,39 @@ define i32 @casts() {
%r136 = fptoui <8 x float> undef to <8 x i32>
; CHECK: Found an estimated cost of 2 for instruction: %r137 = fptosi <8 x float> undef to <8 x i32>
%r137 = fptosi <8 x float> undef to <8 x i32>
- ; CHECK: Found an estimated cost of 128 for instruction: %r138 = fptoui <8 x float> undef to <8 x i64>
+ ; CHECK: Found an estimated cost of 131 for instruction: %r138 = fptoui <8 x float> undef to <8 x i64>
%r138 = fptoui <8 x float> undef to <8 x i64>
- ; CHECK: Found an estimated cost of 128 for instruction: %r139 = fptosi <8 x float> undef to <8 x i64>
+ ; CHECK: Found an estimated cost of 131 for instruction: %r139 = fptosi <8 x float> undef to <8 x i64>
%r139 = fptosi <8 x float> undef to <8 x i64>
- ; CHECK: Found an estimated cost of 64 for instruction: %r140 = fptoui <8 x double> undef to <8 x i1>
+ ; CHECK: Found an estimated cost of 67 for instruction: %r140 = fptoui <8 x double> undef to <8 x i1>
%r140 = fptoui <8 x double> undef to <8 x i1>
- ; CHECK: Found an estimated cost of 64 for instruction: %r141 = fptosi <8 x double> undef to <8 x i1>
+ ; CHECK: Found an estimated cost of 67 for instruction: %r141 = fptosi <8 x double> undef to <8 x i1>
%r141 = fptosi <8 x double> undef to <8 x i1>
- ; CHECK: Found an estimated cost of 64 for instruction: %r142 = fptoui <8 x double> undef to <8 x i8>
+ ; CHECK: Found an estimated cost of 67 for instruction: %r142 = fptoui <8 x double> undef to <8 x i8>
%r142 = fptoui <8 x double> undef to <8 x i8>
- ; CHECK: Found an estimated cost of 64 for instruction: %r143 = fptosi <8 x double> undef to <8 x i8>
+ ; CHECK: Found an estimated cost of 67 for instruction: %r143 = fptosi <8 x double> undef to <8 x i8>
%r143 = fptosi <8 x double> undef to <8 x i8>
- ; CHECK: Found an estimated cost of 64 for instruction: %r144 = fptoui <8 x double> undef to <8 x i16>
+ ; CHECK: Found an estimated cost of 67 for instruction: %r144 = fptoui <8 x double> undef to <8 x i16>
%r144 = fptoui <8 x double> undef to <8 x i16>
- ; CHECK: Found an estimated cost of 64 for instruction: %r145 = fptosi <8 x double> undef to <8 x i16>
+ ; CHECK: Found an estimated cost of 67 for instruction: %r145 = fptosi <8 x double> undef to <8 x i16>
%r145 = fptosi <8 x double> undef to <8 x i16>
- ; CHECK: Found an estimated cost of 64 for instruction: %r146 = fptoui <8 x double> undef to <8 x i32>
+ ; CHECK: Found an estimated cost of 11 for instruction: %r146 = fptoui <8 x double> undef to <8 x i32>
%r146 = fptoui <8 x double> undef to <8 x i32>
- ; CHECK: Found an estimated cost of 64 for instruction: %r147 = fptosi <8 x double> undef to <8 x i32>
+ ; CHECK: Found an estimated cost of 11 for instruction: %r147 = fptosi <8 x double> undef to <8 x i32>
%r147 = fptosi <8 x double> undef to <8 x i32>
- ; CHECK: Found an estimated cost of 128 for instruction: %r148 = fptoui <8 x double> undef to <8 x i64>
+ ; CHECK: Found an estimated cost of 131 for instruction: %r148 = fptoui <8 x double> undef to <8 x i64>
%r148 = fptoui <8 x double> undef to <8 x i64>
- ; CHECK: Found an estimated cost of 128 for instruction: %r149 = fptosi <8 x double> undef to <8 x i64>
+ ; CHECK: Found an estimated cost of 131 for instruction: %r149 = fptosi <8 x double> undef to <8 x i64>
%r149 = fptosi <8 x double> undef to <8 x i64>
- ; CHECK: Found an estimated cost of 128 for instruction: %r150 = fptoui <16 x float> undef to <16 x i1>
+ ; CHECK: Found an estimated cost of 131 for instruction: %r150 = fptoui <16 x float> undef to <16 x i1>
%r150 = fptoui <16 x float> undef to <16 x i1>
- ; CHECK: Found an estimated cost of 128 for instruction: %r151 = fptosi <16 x float> undef to <16 x i1>
+ ; CHECK: Found an estimated cost of 131 for instruction: %r151 = fptosi <16 x float> undef to <16 x i1>
%r151 = fptosi <16 x float> undef to <16 x i1>
- ; CHECK: Found an estimated cost of 128 for instruction: %r152 = fptoui <16 x float> undef to <16 x i8>
+ ; CHECK: Found an estimated cost of 15 for instruction: %r152 = fptoui <16 x float> undef to <16 x i8>
%r152 = fptoui <16 x float> undef to <16 x i8>
- ; CHECK: Found an estimated cost of 128 for instruction: %r153 = fptosi <16 x float> undef to <16 x i8>
+ ; CHECK: Found an estimated cost of 15 for instruction: %r153 = fptosi <16 x float> undef to <16 x i8>
%r153 = fptosi <16 x float> undef to <16 x i8>
; CHECK: Found an estimated cost of 8 for instruction: %r154 = fptoui <16 x float> undef to <16 x i16>
%r154 = fptoui <16 x float> undef to <16 x i16>
@@ -348,30 +348,30 @@ define i32 @casts() {
%r156 = fptoui <16 x float> undef to <16 x i32>
; CHECK: Found an estimated cost of 4 for instruction: %r157 = fptosi <16 x float> undef to <16 x i32>
%r157 = fptosi <16 x float> undef to <16 x i32>
- ; CHECK: Found an estimated cost of 256 for instruction: %r158 = fptoui <16 x float> undef to <16 x i64>
+ ; CHECK: Found an estimated cost of 263 for instruction: %r158 = fptoui <16 x float> undef to <16 x i64>
%r158 = fptoui <16 x float> undef to <16 x i64>
- ; CHECK: Found an estimated cost of 256 for instruction: %r159 = fptosi <16 x float> undef to <16 x i64>
+ ; CHECK: Found an estimated cost of 263 for instruction: %r159 = fptosi <16 x float> undef to <16 x i64>
%r159 = fptosi <16 x float> undef to <16 x i64>
- ; CHECK: Found an estimated cost of 128 for instruction: %r160 = fptoui <16 x double> undef to <16 x i1>
+ ; CHECK: Found an estimated cost of 135 for instruction: %r160 = fptoui <16 x double> undef to <16 x i1>
%r160 = fptoui <16 x double> undef to <16 x i1>
- ; CHECK: Found an estimated cost of 128 for instruction: %r161 = fptosi <16 x double> undef to <16 x i1>
+ ; CHECK: Found an estimated cost of 135 for instruction: %r161 = fptosi <16 x double> undef to <16 x i1>
%r161 = fptosi <16 x double> undef to <16 x i1>
- ; CHECK: Found an estimated cost of 128 for instruction: %r162 = fptoui <16 x double> undef to <16 x i8>
+ ; CHECK: Found an estimated cost of 135 for instruction: %r162 = fptoui <16 x double> undef to <16 x i8>
%r162 = fptoui <16 x double> undef to <16 x i8>
- ; CHECK: Found an estimated cost of 128 for instruction: %r163 = fptosi <16 x double> undef to <16 x i8>
+ ; CHECK: Found an estimated cost of 135 for instruction: %r163 = fptosi <16 x double> undef to <16 x i8>
%r163 = fptosi <16 x double> undef to <16 x i8>
- ; CHECK: Found an estimated cost of 128 for instruction: %r164 = fptoui <16 x double> undef to <16 x i16>
+ ; CHECK: Found an estimated cost of 135 for instruction: %r164 = fptoui <16 x double> undef to <16 x i16>
%r164 = fptoui <16 x double> undef to <16 x i16>
- ; CHECK: Found an estimated cost of 128 for instruction: %r165 = fptosi <16 x double> undef to <16 x i16>
+ ; CHECK: Found an estimated cost of 135 for instruction: %r165 = fptosi <16 x double> undef to <16 x i16>
%r165 = fptosi <16 x double> undef to <16 x i16>
- ; CHECK: Found an estimated cost of 128 for instruction: %r166 = fptoui <16 x double> undef to <16 x i32>
+ ; CHECK: Found an estimated cost of 23 for instruction: %r166 = fptoui <16 x double> undef to <16 x i32>
%r166 = fptoui <16 x double> undef to <16 x i32>
- ; CHECK: Found an estimated cost of 128 for instruction: %r167 = fptosi <16 x double> undef to <16 x i32>
+ ; CHECK: Found an estimated cost of 23 for instruction: %r167 = fptosi <16 x double> undef to <16 x i32>
%r167 = fptosi <16 x double> undef to <16 x i32>
- ; CHECK: Found an estimated cost of 256 for instruction: %r168 = fptoui <16 x double> undef to <16 x i64>
+ ; CHECK: Found an estimated cost of 263 for instruction: %r168 = fptoui <16 x double> undef to <16 x i64>
%r168 = fptoui <16 x double> undef to <16 x i64>
- ; CHECK: Found an estimated cost of 256 for instruction: %r169 = fptosi <16 x double> undef to <16 x i64>
+ ; CHECK: Found an estimated cost of 263 for instruction: %r169 = fptosi <16 x double> undef to <16 x i64>
%r169 = fptosi <16 x double> undef to <16 x i64>
; CHECK: Found an estimated cost of 12 for instruction: %r170 = uitofp <2 x i1> undef to <2 x float>
@@ -432,39 +432,39 @@ define i32 @casts() {
%r196 = uitofp <4 x i32> undef to <4 x float>
; CHECK: Found an estimated cost of 1 for instruction: %r197 = sitofp <4 x i32> undef to <4 x float>
%r197 = sitofp <4 x i32> undef to <4 x float>
- ; CHECK: Found an estimated cost of 56 for instruction: %r198 = uitofp <4 x i64> undef to <4 x float>
+ ; CHECK: Found an estimated cost of 57 for instruction: %r198 = uitofp <4 x i64> undef to <4 x float>
%r198 = uitofp <4 x i64> undef to <4 x float>
- ; CHECK: Found an estimated cost of 56 for instruction: %r199 = sitofp <4 x i64> undef to <4 x float>
+ ; CHECK: Found an estimated cost of 57 for instruction: %r199 = sitofp <4 x i64> undef to <4 x float>
%r199 = sitofp <4 x i64> undef to <4 x float>
- ; CHECK: Found an estimated cost of 16 for instruction: %r200 = uitofp <4 x i1> undef to <4 x double>
+ ; CHECK: Found an estimated cost of 17 for instruction: %r200 = uitofp <4 x i1> undef to <4 x double>
%r200 = uitofp <4 x i1> undef to <4 x double>
- ; CHECK: Found an estimated cost of 16 for instruction: %r201 = sitofp <4 x i1> undef to <4 x double>
+ ; CHECK: Found an estimated cost of 17 for instruction: %r201 = sitofp <4 x i1> undef to <4 x double>
%r201 = sitofp <4 x i1> undef to <4 x double>
- ; CHECK: Found an estimated cost of 16 for instruction: %r202 = uitofp <4 x i8> undef to <4 x double>
+ ; CHECK: Found an estimated cost of 9 for instruction: %r202 = uitofp <4 x i8> undef to <4 x double>
%r202 = uitofp <4 x i8> undef to <4 x double>
- ; CHECK: Found an estimated cost of 16 for instruction: %r203 = sitofp <4 x i8> undef to <4 x double>
+ ; CHECK: Found an estimated cost of 9 for instruction: %r203 = sitofp <4 x i8> undef to <4 x double>
%r203 = sitofp <4 x i8> undef to <4 x double>
- ; CHECK: Found an estimated cost of 16 for instruction: %r204 = uitofp <4 x i16> undef to <4 x double>
+ ; CHECK: Found an estimated cost of 7 for instruction: %r204 = uitofp <4 x i16> undef to <4 x double>
%r204 = uitofp <4 x i16> undef to <4 x double>
- ; CHECK: Found an estimated cost of 16 for instruction: %r205 = sitofp <4 x i16> undef to <4 x double>
+ ; CHECK: Found an estimated cost of 7 for instruction: %r205 = sitofp <4 x i16> undef to <4 x double>
%r205 = sitofp <4 x i16> undef to <4 x double>
- ; CHECK: Found an estimated cost of 16 for instruction: %r206 = uitofp <4 x i32> undef to <4 x double>
+ ; CHECK: Found an estimated cost of 5 for instruction: %r206 = uitofp <4 x i32> undef to <4 x double>
%r206 = uitofp <4 x i32> undef to <4 x double>
- ; CHECK: Found an estimated cost of 16 for instruction: %r207 = sitofp <4 x i32> undef to <4 x double>
+ ; CHECK: Found an estimated cost of 5 for instruction: %r207 = sitofp <4 x i32> undef to <4 x double>
%r207 = sitofp <4 x i32> undef to <4 x double>
- ; CHECK: Found an estimated cost of 48 for instruction: %r208 = uitofp <4 x i64> undef to <4 x double>
+ ; CHECK: Found an estimated cost of 49 for instruction: %r208 = uitofp <4 x i64> undef to <4 x double>
%r208 = uitofp <4 x i64> undef to <4 x double>
- ; CHECK: Found an estimated cost of 48 for instruction: %r209 = sitofp <4 x i64> undef to <4 x double>
+ ; CHECK: Found an estimated cost of 49 for instruction: %r209 = sitofp <4 x i64> undef to <4 x double>
%r209 = sitofp <4 x i64> undef to <4 x double>
- ; CHECK: Found an estimated cost of 48 for instruction: %r210 = uitofp <8 x i1> undef to <8 x float>
+ ; CHECK: Found an estimated cost of 7 for instruction: %r210 = uitofp <8 x i1> undef to <8 x float>
%r210 = uitofp <8 x i1> undef to <8 x float>
- ; CHECK: Found an estimated cost of 48 for instruction: %r211 = sitofp <8 x i1> undef to <8 x float>
+ ; CHECK: Found an estimated cost of 7 for instruction: %r211 = sitofp <8 x i1> undef to <8 x float>
%r211 = sitofp <8 x i1> undef to <8 x float>
- ; CHECK: Found an estimated cost of 48 for instruction: %r212 = uitofp <8 x i8> undef to <8 x float>
+ ; CHECK: Found an estimated cost of 7 for instruction: %r212 = uitofp <8 x i8> undef to <8 x float>
%r212 = uitofp <8 x i8> undef to <8 x float>
- ; CHECK: Found an estimated cost of 48 for instruction: %r213 = sitofp <8 x i8> undef to <8 x float>
+ ; CHECK: Found an estimated cost of 7 for instruction: %r213 = sitofp <8 x i8> undef to <8 x float>
%r213 = sitofp <8 x i8> undef to <8 x float>
; CHECK: Found an estimated cost of 4 for instruction: %r214 = uitofp <8 x i16> undef to <8 x float>
%r214 = uitofp <8 x i16> undef to <8 x float>
@@ -474,39 +474,39 @@ define i32 @casts() {
%r216 = uitofp <8 x i32> undef to <8 x float>
; CHECK: Found an estimated cost of 2 for instruction: %r217 = sitofp <8 x i32> undef to <8 x float>
%r217 = sitofp <8 x i32> undef to <8 x float>
- ; CHECK: Found an estimated cost of 112 for instruction: %r218 = uitofp <8 x i64> undef to <8 x float>
+ ; CHECK: Found an estimated cost of 115 for instruction: %r218 = uitofp <8 x i64> undef to <8 x float>
%r218 = uitofp <8 x i64> undef to <8 x float>
- ; CHECK: Found an estimated cost of 112 for instruction: %r219 = sitofp <8 x i64> undef to <8 x float>
+ ; CHECK: Found an estimated cost of 115 for instruction: %r219 = sitofp <8 x i64> undef to <8 x float>
%r219 = sitofp <8 x i64> undef to <8 x float>
- ; CHECK: Found an estimated cost of 32 for instruction: %r220 = uitofp <8 x i1> undef to <8 x double>
+ ; CHECK: Found an estimated cost of 35 for instruction: %r220 = uitofp <8 x i1> undef to <8 x double>
%r220 = uitofp <8 x i1> undef to <8 x double>
- ; CHECK: Found an estimated cost of 32 for instruction: %r221 = sitofp <8 x i1> undef to <8 x double>
+ ; CHECK: Found an estimated cost of 35 for instruction: %r221 = sitofp <8 x i1> undef to <8 x double>
%r221 = sitofp <8 x i1> undef to <8 x double>
- ; CHECK: Found an estimated cost of 32 for instruction: %r222 = uitofp <8 x i8> undef to <8 x double>
+ ; CHECK: Found an estimated cost of 19 for instruction: %r222 = uitofp <8 x i8> undef to <8 x double>
%r222 = uitofp <8 x i8> undef to <8 x double>
- ; CHECK: Found an estimated cost of 32 for instruction: %r223 = sitofp <8 x i8> undef to <8 x double>
+ ; CHECK: Found an estimated cost of 19 for instruction: %r223 = sitofp <8 x i8> undef to <8 x double>
%r223 = sitofp <8 x i8> undef to <8 x double>
- ; CHECK: Found an estimated cost of 32 for instruction: %r224 = uitofp <8 x i16> undef to <8 x double>
+ ; CHECK: Found an estimated cost of 15 for instruction: %r224 = uitofp <8 x i16> undef to <8 x double>
%r224 = uitofp <8 x i16> undef to <8 x double>
- ; CHECK: Found an estimated cost of 32 for instruction: %r225 = sitofp <8 x i16> undef to <8 x double>
+ ; CHECK: Found an estimated cost of 15 for instruction: %r225 = sitofp <8 x i16> undef to <8 x double>
%r225 = sitofp <8 x i16> undef to <8 x double>
- ; CHECK: Found an estimated cost of 32 for instruction: %r226 = uitofp <8 x i16> undef to <8 x double>
+ ; CHECK: Found an estimated cost of 15 for instruction: %r226 = uitofp <8 x i16> undef to <8 x double>
%r226 = uitofp <8 x i16> undef to <8 x double>
- ; CHECK: Found an estimated cost of 32 for instruction: %r227 = sitofp <8 x i16> undef to <8 x double>
+ ; CHECK: Found an estimated cost of 15 for instruction: %r227 = sitofp <8 x i16> undef to <8 x double>
%r227 = sitofp <8 x i16> undef to <8 x double>
- ; CHECK: Found an estimated cost of 96 for instruction: %r228 = uitofp <8 x i64> undef to <8 x double>
+ ; CHECK: Found an estimated cost of 99 for instruction: %r228 = uitofp <8 x i64> undef to <8 x double>
%r228 = uitofp <8 x i64> undef to <8 x double>
- ; CHECK: Found an estimated cost of 96 for instruction: %r229 = sitofp <8 x i64> undef to <8 x double>
+ ; CHECK: Found an estimated cost of 99 for instruction: %r229 = sitofp <8 x i64> undef to <8 x double>
%r229 = sitofp <8 x i64> undef to <8 x double>
- ; CHECK: Found an estimated cost of 96 for instruction: %r230 = uitofp <16 x i1> undef to <16 x float>
+ ; CHECK: Found an estimated cost of 15 for instruction: %r230 = uitofp <16 x i1> undef to <16 x float>
%r230 = uitofp <16 x i1> undef to <16 x float>
- ; CHECK: Found an estimated cost of 96 for instruction: %r231 = sitofp <16 x i1> undef to <16 x float>
+ ; CHECK: Found an estimated cost of 15 for instruction: %r231 = sitofp <16 x i1> undef to <16 x float>
%r231 = sitofp <16 x i1> undef to <16 x float>
- ; CHECK: Found an estimated cost of 96 for instruction: %r232 = uitofp <16 x i8> undef to <16 x float>
+ ; CHECK: Found an estimated cost of 15 for instruction: %r232 = uitofp <16 x i8> undef to <16 x float>
%r232 = uitofp <16 x i8> undef to <16 x float>
- ; CHECK: Found an estimated cost of 96 for instruction: %r233 = sitofp <16 x i8> undef to <16 x float>
+ ; CHECK: Found an estimated cost of 15 for instruction: %r233 = sitofp <16 x i8> undef to <16 x float>
%r233 = sitofp <16 x i8> undef to <16 x float>
; CHECK: Found an estimated cost of 8 for instruction: %r234 = uitofp <16 x i16> undef to <16 x float>
%r234 = uitofp <16 x i16> undef to <16 x float>
@@ -516,30 +516,30 @@ define i32 @casts() {
%r236 = uitofp <16 x i32> undef to <16 x float>
; CHECK: Found an estimated cost of 4 for instruction: %r237 = sitofp <16 x i32> undef to <16 x float>
%r237 = sitofp <16 x i32> undef to <16 x float>
- ; CHECK: Found an estimated cost of 224 for instruction: %r238 = uitofp <16 x i64> undef to <16 x float>
+ ; CHECK: Found an estimated cost of 231 for instruction: %r238 = uitofp <16 x i64> undef to <16 x float>
%r238 = uitofp <16 x i64> undef to <16 x float>
- ; CHECK: Found an estimated cost of 224 for instruction: %r239 = sitofp <16 x i64> undef to <16 x float>
+ ; CHECK: Found an estimated cost of 231 for instruction: %r239 = sitofp <16 x i64> undef to <16 x float>
%r239 = sitofp <16 x i64> undef to <16 x float>
- ; CHECK: Found an estimated cost of 64 for instruction: %r240 = uitofp <16 x i1> undef to <16 x double>
+ ; CHECK: Found an estimated cost of 71 for instruction: %r240 = uitofp <16 x i1> undef to <16 x double>
%r240 = uitofp <16 x i1> undef to <16 x double>
- ; CHECK: Found an estimated cost of 64 for instruction: %r241 = sitofp <16 x i1> undef to <16 x double>
+ ; CHECK: Found an estimated cost of 71 for instruction: %r241 = sitofp <16 x i1> undef to <16 x double>
%r241 = sitofp <16 x i1> undef to <16 x double>
- ; CHECK: Found an estimated cost of 64 for instruction: %r242 = uitofp <16 x i8> undef to <16 x double>
+ ; CHECK: Found an estimated cost of 39 for instruction: %r242 = uitofp <16 x i8> undef to <16 x double>
%r242 = uitofp <16 x i8> undef to <16 x double>
- ; CHECK: Found an estimated cost of 64 for instruction: %r243 = sitofp <16 x i8> undef to <16 x double>
+ ; CHECK: Found an estimated cost of 39 for instruction: %r243 = sitofp <16 x i8> undef to <16 x double>
%r243 = sitofp <16 x i8> undef to <16 x double>
- ; CHECK: Found an estimated cost of 64 for instruction: %r244 = uitofp <16 x i16> undef to <16 x double>
+ ; CHECK: Found an estimated cost of 31 for instruction: %r244 = uitofp <16 x i16> undef to <16 x double>
%r244 = uitofp <16 x i16> undef to <16 x double>
- ; CHECK: Found an estimated cost of 64 for instruction: %r245 = sitofp <16 x i16> undef to <16 x double>
+ ; CHECK: Found an estimated cost of 31 for instruction: %r245 = sitofp <16 x i16> undef to <16 x double>
%r245 = sitofp <16 x i16> undef to <16 x double>
- ; CHECK: Found an estimated cost of 64 for instruction: %r246 = uitofp <16 x i16> undef to <16 x double>
+ ; CHECK: Found an estimated cost of 31 for instruction: %r246 = uitofp <16 x i16> undef to <16 x double>
%r246 = uitofp <16 x i16> undef to <16 x double>
- ; CHECK: Found an estimated cost of 64 for instruction: %r247 = sitofp <16 x i16> undef to <16 x double>
+ ; CHECK: Found an estimated cost of 31 for instruction: %r247 = sitofp <16 x i16> undef to <16 x double>
%r247 = sitofp <16 x i16> undef to <16 x double>
- ; CHECK: Found an estimated cost of 192 for instruction: %r248 = uitofp <16 x i64> undef to <16 x double>
+ ; CHECK: Found an estimated cost of 199 for instruction: %r248 = uitofp <16 x i64> undef to <16 x double>
%r248 = uitofp <16 x i64> undef to <16 x double>
- ; CHECK: Found an estimated cost of 192 for instruction: %r249 = sitofp <16 x i64> undef to <16 x double>
+ ; CHECK: Found an estimated cost of 199 for instruction: %r249 = sitofp <16 x i64> undef to <16 x double>
%r249 = sitofp <16 x i64> undef to <16 x double>
; CHECK: Found an estimated cost of 0 for instruction: ret i32 undef
diff --git a/test/Analysis/CostModel/PowerPC/ext.ll b/test/Analysis/CostModel/PowerPC/ext.ll
index 7d6a14e93cdf3..df9c53e6e57f5 100644
--- a/test/Analysis/CostModel/PowerPC/ext.ll
+++ b/test/Analysis/CostModel/PowerPC/ext.ll
@@ -13,7 +13,7 @@ define void @exts() {
; CHECK: cost of 1 {{.*}} sext
%v3 = sext <4 x i16> undef to <4 x i32>
- ; CHECK: cost of 112 {{.*}} sext
+ ; CHECK: cost of 3 {{.*}} sext
%v4 = sext <8 x i16> undef to <8 x i32>
ret void
diff --git a/test/Analysis/CostModel/PowerPC/load_store.ll b/test/Analysis/CostModel/PowerPC/load_store.ll
index 0a568b88e7269..d48be5b5f62be 100644
--- a/test/Analysis/CostModel/PowerPC/load_store.ll
+++ b/test/Analysis/CostModel/PowerPC/load_store.ll
@@ -31,7 +31,7 @@ define i32 @loads(i32 %arg) {
; FIXME: There actually are sub-vector Altivec loads, and so we could handle
; this with a small expense, but we don't currently.
- ; CHECK: cost of 48 {{.*}} load
+ ; CHECK: cost of 42 {{.*}} load
load <4 x i16>, <4 x i16>* undef, align 2
; CHECK: cost of 2 {{.*}} load
diff --git a/test/Analysis/CostModel/PowerPC/popcnt.ll b/test/Analysis/CostModel/PowerPC/popcnt.ll
new file mode 100644
index 0000000000000..4bd842db09b65
--- /dev/null
+++ b/test/Analysis/CostModel/PowerPC/popcnt.ll
@@ -0,0 +1,11 @@
+; RUN: opt < %s -cost-model -analyze -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 | 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"
+
+define <4 x i32> @test1(<4 x i32> %arg) {
+ ; CHECK: cost of 1 {{.*}} call <4 x i32> @llvm.ctpop.v4i32
+ %ctpop = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %arg)
+ ret <4 x i32> %ctpop
+}
+
+declare <4 x i32> @llvm.ctpop.v4i32(<4 x i32>)
diff --git a/test/Analysis/CostModel/X86/arith.ll b/test/Analysis/CostModel/X86/arith.ll
index 0b61d3cd42140..a35db9c68ffb6 100644
--- a/test/Analysis/CostModel/X86/arith.ll
+++ b/test/Analysis/CostModel/X86/arith.ll
@@ -1,128 +1,173 @@
-; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx | FileCheck %s
-; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=core2 | FileCheck %s --check-prefix=SSE3
-; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=core-avx2 | FileCheck %s --check-prefix=AVX2
+; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mattr=+ssse3 | FileCheck %s --check-prefix=CHECK --check-prefix=SSSE3
+; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mattr=+sse4.2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE42
+; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mattr=+avx | FileCheck %s --check-prefix=CHECK --check-prefix=AVX
+; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mattr=+avx2 | FileCheck %s --check-prefix=CHECK --check-prefix=AVX2
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.8.0"
+; CHECK-LABEL: 'add'
define i32 @add(i32 %arg) {
- ;CHECK: cost of 1 {{.*}} add
+ ; SSSE3: cost of 1 {{.*}} %A = add
+ ; SSE42: cost of 1 {{.*}} %A = add
+ ; AVX: cost of 1 {{.*}} %A = add
+ ; AVX2: cost of 1 {{.*}} %A = add
%A = add <4 x i32> undef, undef
- ;CHECK: cost of 4 {{.*}} add
+ ; SSSE3: cost of 2 {{.*}} %B = add
+ ; SSE42: cost of 2 {{.*}} %B = add
+ ; AVX: cost of 4 {{.*}} %B = add
+ ; AVX2: cost of 1 {{.*}} %B = add
%B = add <8 x i32> undef, undef
- ;CHECK: cost of 1 {{.*}} add
+ ; SSSE3: cost of 1 {{.*}} %C = add
+ ; SSE42: cost of 1 {{.*}} %C = add
+ ; AVX: cost of 1 {{.*}} %C = add
+ ; AVX2: cost of 1 {{.*}} %C = add
%C = add <2 x i64> undef, undef
- ;CHECK: cost of 4 {{.*}} add
+ ; SSSE3: cost of 2 {{.*}} %D = add
+ ; SSE42: cost of 2 {{.*}} %D = add
+ ; AVX: cost of 4 {{.*}} %D = add
+ ; AVX2: cost of 1 {{.*}} %D = add
%D = add <4 x i64> undef, undef
- ;CHECK: cost of 8 {{.*}} add
+ ; SSSE3: cost of 4 {{.*}} %E = add
+ ; SSE42: cost of 4 {{.*}} %E = add
+ ; AVX: cost of 8 {{.*}} %E = add
+ ; AVX2: cost of 2 {{.*}} %E = add
%E = add <8 x i64> undef, undef
- ;CHECK: cost of 0 {{.*}} ret
ret i32 undef
}
-
+; CHECK-LABEL: 'xor'
define i32 @xor(i32 %arg) {
- ;CHECK: cost of 1 {{.*}} xor
+ ; SSSE3: cost of 1 {{.*}} %A = xor
+ ; SSE42: cost of 1 {{.*}} %A = xor
+ ; AVX: cost of 1 {{.*}} %A = xor
+ ; AVX2: cost of 1 {{.*}} %A = xor
%A = xor <4 x i32> undef, undef
- ;CHECK: cost of 1 {{.*}} xor
+ ; SSSE3: cost of 2 {{.*}} %B = xor
+ ; SSE42: cost of 2 {{.*}} %B = xor
+ ; AVX: cost of 1 {{.*}} %B = xor
+ ; AVX2: cost of 1 {{.*}} %B = xor
%B = xor <8 x i32> undef, undef
- ;CHECK: cost of 1 {{.*}} xor
+ ; SSSE3: cost of 1 {{.*}} %C = xor
+ ; SSE42: cost of 1 {{.*}} %C = xor
+ ; AVX: cost of 1 {{.*}} %C = xor
+ ; AVX2: cost of 1 {{.*}} %C = xor
%C = xor <2 x i64> undef, undef
- ;CHECK: cost of 1 {{.*}} xor
+ ; SSSE3: cost of 2 {{.*}} %D = xor
+ ; SSE42: cost of 2 {{.*}} %D = xor
+ ; AVX: cost of 1 {{.*}} %D = xor
+ ; AVX2: cost of 1 {{.*}} %D = xor
%D = xor <4 x i64> undef, undef
- ;CHECK: cost of 0 {{.*}} ret
ret i32 undef
}
-; CHECK: mul
+; CHECK-LABEL: 'mul'
define void @mul() {
; A <2 x i32> gets expanded to a <2 x i64> vector.
; A <2 x i64> vector multiply is implemented using
; 3 PMULUDQ and 2 PADDS and 4 shifts.
- ;CHECK: cost of 9 {{.*}} mul
+ ; SSSE3: cost of 9 {{.*}} %A0 = mul
+ ; SSE42: cost of 9 {{.*}} %A0 = mul
+ ; AVX: cost of 9 {{.*}} %A0 = mul
+ ; AVX2: cost of 9 {{.*}} %A0 = mul
%A0 = mul <2 x i32> undef, undef
- ;CHECK: cost of 9 {{.*}} mul
- %A1 = mul <2 x i64> undef, undef
- ;CHECK: cost of 18 {{.*}} mul
- %A2 = mul <4 x i64> undef, undef
- ret void
-}
-
-; SSE3: sse3mull
-define void @sse3mull() {
- ; SSE3: cost of 6 {{.*}} mul
- %A0 = mul <4 x i32> undef, undef
- ret void
- ; SSE3: avx2mull
-}
-
-; AVX2: avx2mull
-define void @avx2mull() {
- ; AVX2: cost of 9 {{.*}} mul
- %A0 = mul <4 x i64> undef, undef
+ ; SSSE3: cost of 6 {{.*}} %A1 = mul
+ ; SSE42: cost of 1 {{.*}} %A1 = mul
+ ; AVX: cost of 1 {{.*}} %A1 = mul
+ ; AVX2: cost of 1 {{.*}} %A1 = mul
+ %A1 = mul <4 x i32> undef, undef
+ ; SSSE3: cost of 9 {{.*}} %A2 = mul
+ ; SSE42: cost of 9 {{.*}} %A2 = mul
+ ; AVX: cost of 9 {{.*}} %A2 = mul
+ ; AVX2: cost of 9 {{.*}} %A2 = mul
+ %A2 = mul <2 x i64> undef, undef
+ ; SSSE3: cost of 18 {{.*}} %A3 = mul
+ ; SSE42: cost of 18 {{.*}} %A3 = mul
+ ; AVX: cost of 18 {{.*}} %A3 = mul
+ ; AVX2: cost of 9 {{.*}} %A3 = mul
+ %A3 = mul <4 x i64> undef, undef
ret void
- ; AVX2: fmul
}
-; CHECK: fmul
+; CHECK-LABEL: 'fmul'
define i32 @fmul(i32 %arg) {
- ;CHECK: cost of 2 {{.*}} fmul
+ ; SSSE3: cost of 2 {{.*}} %A = fmul
+ ; SSE42: cost of 2 {{.*}} %A = fmul
+ ; AVX: cost of 2 {{.*}} %A = fmul
+ ; AVX2: cost of 2 {{.*}} %A = fmul
%A = fmul <4 x float> undef, undef
- ;CHECK: cost of 2 {{.*}} fmul
+ ; SSSE3: cost of 4 {{.*}} %B = fmul
+ ; SSE42: cost of 4 {{.*}} %B = fmul
+ ; AVX: cost of 2 {{.*}} %B = fmul
+ ; AVX2: cost of 2 {{.*}} %B = fmul
%B = fmul <8 x float> undef, undef
ret i32 undef
}
-; AVX: shift
-; AVX2: shift
+; CHECK-LABEL: 'shift'
define void @shift() {
- ; AVX: cost of 2 {{.*}} shl
- ; AVX2: cost of 1 {{.*}} shl
+ ; SSSE3: cost of 10 {{.*}} %A0 = shl
+ ; SSE42: cost of 10 {{.*}} %A0 = shl
+ ; AVX: cost of 10 {{.*}} %A0 = shl
+ ; AVX2: cost of 1 {{.*}} %A0 = shl
%A0 = shl <4 x i32> undef, undef
- ; AVX: cost of 2 {{.*}} shl
- ; AVX2: cost of 1 {{.*}} shl
+ ; SSSE3: cost of 4 {{.*}} %A1 = shl
+ ; SSE42: cost of 4 {{.*}} %A1 = shl
+ ; AVX: cost of 4 {{.*}} %A1 = shl
+ ; AVX2: cost of 1 {{.*}} %A1 = shl
%A1 = shl <2 x i64> undef, undef
+ ; SSSE3: cost of 20 {{.*}} %A2 = shl
+ ; SSE42: cost of 20 {{.*}} %A2 = shl
+ ; AVX: cost of 20 {{.*}} %A2 = shl
+ ; AVX2: cost of 1 {{.*}} %A2 = shl
+ %A2 = shl <8 x i32> undef, undef
+ ; SSSE3: cost of 8 {{.*}} %A3 = shl
+ ; SSE42: cost of 8 {{.*}} %A3 = shl
+ ; AVX: cost of 8 {{.*}} %A3 = shl
+ ; AVX2: cost of 1 {{.*}} %A3 = shl
+ %A3 = shl <4 x i64> undef, undef
- ; AVX: cost of 2 {{.*}} lshr
- ; AVX2: cost of 1 {{.*}} lshr
+ ; SSSE3: cost of 16 {{.*}} %B0 = lshr
+ ; SSE42: cost of 16 {{.*}} %B0 = lshr
+ ; AVX: cost of 16 {{.*}} %B0 = lshr
+ ; AVX2: cost of 1 {{.*}} %B0 = lshr
%B0 = lshr <4 x i32> undef, undef
- ; AVX: cost of 2 {{.*}} lshr
- ; AVX2: cost of 1 {{.*}} lshr
+ ; SSSE3: cost of 4 {{.*}} %B1 = lshr
+ ; SSE42: cost of 4 {{.*}} %B1 = lshr
+ ; AVX: cost of 4 {{.*}} %B1 = lshr
+ ; AVX2: cost of 1 {{.*}} %B1 = lshr
%B1 = lshr <2 x i64> undef, undef
+ ; SSSE3: cost of 32 {{.*}} %B2 = lshr
+ ; SSE42: cost of 32 {{.*}} %B2 = lshr
+ ; AVX: cost of 32 {{.*}} %B2 = lshr
+ ; AVX2: cost of 1 {{.*}} %B2 = lshr
+ %B2 = lshr <8 x i32> undef, undef
+ ; SSSE3: cost of 8 {{.*}} %B3 = lshr
+ ; SSE42: cost of 8 {{.*}} %B3 = lshr
+ ; AVX: cost of 8 {{.*}} %B3 = lshr
+ ; AVX2: cost of 1 {{.*}} %B3 = lshr
+ %B3 = lshr <4 x i64> undef, undef
- ; AVX: cost of 2 {{.*}} ashr
- ; AVX2: cost of 1 {{.*}} ashr
+ ; SSSE3: cost of 16 {{.*}} %C0 = ashr
+ ; SSE42: cost of 16 {{.*}} %C0 = ashr
+ ; AVX: cost of 16 {{.*}} %C0 = ashr
+ ; AVX2: cost of 1 {{.*}} %C0 = ashr
%C0 = ashr <4 x i32> undef, undef
- ; AVX: cost of 6 {{.*}} ashr
- ; AVX2: cost of 4 {{.*}} ashr
+ ; SSSE3: cost of 12 {{.*}} %C1 = ashr
+ ; SSE42: cost of 12 {{.*}} %C1 = ashr
+ ; AVX: cost of 12 {{.*}} %C1 = ashr
+ ; AVX2: cost of 4 {{.*}} %C1 = ashr
%C1 = ashr <2 x i64> undef, undef
-
- ret void
-}
-
-; AVX: avx2shift
-; AVX2: avx2shift
-define void @avx2shift() {
- ; AVX: cost of 2 {{.*}} shl
- ; AVX2: cost of 1 {{.*}} shl
- %A0 = shl <8 x i32> undef, undef
- ; AVX: cost of 2 {{.*}} shl
- ; AVX2: cost of 1 {{.*}} shl
- %A1 = shl <4 x i64> undef, undef
-
- ; AVX: cost of 2 {{.*}} lshr
- ; AVX2: cost of 1 {{.*}} lshr
- %B0 = lshr <8 x i32> undef, undef
- ; AVX: cost of 2 {{.*}} lshr
- ; AVX2: cost of 1 {{.*}} lshr
- %B1 = lshr <4 x i64> undef, undef
-
- ; AVX: cost of 2 {{.*}} ashr
- ; AVX2: cost of 1 {{.*}} ashr
- %C0 = ashr <8 x i32> undef, undef
- ; AVX: cost of 12 {{.*}} ashr
- ; AVX2: cost of 4 {{.*}} ashr
- %C1 = ashr <4 x i64> undef, undef
+ ; SSSE3: cost of 32 {{.*}} %C2 = ashr
+ ; SSE42: cost of 32 {{.*}} %C2 = ashr
+ ; AVX: cost of 32 {{.*}} %C2 = ashr
+ ; AVX2: cost of 1 {{.*}} %C2 = ashr
+ %C2 = ashr <8 x i32> undef, undef
+ ; SSSE3: cost of 24 {{.*}} %C3 = ashr
+ ; SSE42: cost of 24 {{.*}} %C3 = ashr
+ ; AVX: cost of 24 {{.*}} %C3 = ashr
+ ; AVX2: cost of 4 {{.*}} %C3 = ashr
+ %C3 = ashr <4 x i64> undef, undef
ret void
}
diff --git a/test/Analysis/CostModel/X86/bitreverse.ll b/test/Analysis/CostModel/X86/bitreverse.ll
new file mode 100644
index 0000000000000..c9eea20c3404d
--- /dev/null
+++ b/test/Analysis/CostModel/X86/bitreverse.ll
@@ -0,0 +1,157 @@
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=pentium4 -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=SSE2
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=SSE42
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7-avx -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=AVX
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=core-avx2 -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=AVX2
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=bdver2 -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=XOP -check-prefix=XOPAVX
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=bdver4 -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=XOP -check-prefix=XOPAVX2
+
+; Verify the cost of scalar bitreverse instructions.
+
+declare i64 @llvm.bitreverse.i64(i64)
+declare i32 @llvm.bitreverse.i32(i32)
+declare i16 @llvm.bitreverse.i16(i16)
+declare i8 @llvm.bitreverse.i8(i8)
+
+define i64 @var_bitreverse_i64(i64 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bitreverse_i64':
+; SSE2: Found an estimated cost of 1 for instruction: %bitreverse
+; SSE42: Found an estimated cost of 1 for instruction: %bitreverse
+; AVX: Found an estimated cost of 1 for instruction: %bitreverse
+; AVX2: Found an estimated cost of 1 for instruction: %bitreverse
+; XOP: Found an estimated cost of 3 for instruction: %bitreverse
+ %bitreverse = call i64 @llvm.bitreverse.i64(i64 %a)
+ ret i64 %bitreverse
+}
+
+define i32 @var_bitreverse_i32(i32 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bitreverse_i32':
+; SSE2: Found an estimated cost of 1 for instruction: %bitreverse
+; SSE42: Found an estimated cost of 1 for instruction: %bitreverse
+; AVX: Found an estimated cost of 1 for instruction: %bitreverse
+; AVX2: Found an estimated cost of 1 for instruction: %bitreverse
+; XOP: Found an estimated cost of 3 for instruction: %bitreverse
+ %bitreverse = call i32 @llvm.bitreverse.i32(i32 %a)
+ ret i32 %bitreverse
+}
+
+define i16 @var_bitreverse_i16(i16 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bitreverse_i16':
+; SSE2: Found an estimated cost of 1 for instruction: %bitreverse
+; SSE42: Found an estimated cost of 1 for instruction: %bitreverse
+; AVX: Found an estimated cost of 1 for instruction: %bitreverse
+; AVX2: Found an estimated cost of 1 for instruction: %bitreverse
+; XOP: Found an estimated cost of 3 for instruction: %bitreverse
+ %bitreverse = call i16 @llvm.bitreverse.i16(i16 %a)
+ ret i16 %bitreverse
+}
+
+define i8 @var_bitreverse_i8(i8 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bitreverse_i8':
+; SSE2: Found an estimated cost of 1 for instruction: %bitreverse
+; SSE42: Found an estimated cost of 1 for instruction: %bitreverse
+; AVX: Found an estimated cost of 1 for instruction: %bitreverse
+; AVX2: Found an estimated cost of 1 for instruction: %bitreverse
+; XOP: Found an estimated cost of 3 for instruction: %bitreverse
+ %bitreverse = call i8 @llvm.bitreverse.i8(i8 %a)
+ ret i8 %bitreverse
+}
+
+; Verify the cost of vector bitreverse instructions.
+
+declare <2 x i64> @llvm.bitreverse.v2i64(<2 x i64>)
+declare <4 x i32> @llvm.bitreverse.v4i32(<4 x i32>)
+declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>)
+declare <16 x i8> @llvm.bitreverse.v16i8(<16 x i8>)
+
+declare <4 x i64> @llvm.bitreverse.v4i64(<4 x i64>)
+declare <8 x i32> @llvm.bitreverse.v8i32(<8 x i32>)
+declare <16 x i16> @llvm.bitreverse.v16i16(<16 x i16>)
+declare <32 x i8> @llvm.bitreverse.v32i8(<32 x i8>)
+
+define <2 x i64> @var_bitreverse_v2i64(<2 x i64> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bitreverse_v2i64':
+; SSE2: Found an estimated cost of 6 for instruction: %bitreverse
+; SSE42: Found an estimated cost of 5 for instruction: %bitreverse
+; AVX: Found an estimated cost of 5 for instruction: %bitreverse
+; AVX2: Found an estimated cost of 5 for instruction: %bitreverse
+; XOP: Found an estimated cost of 1 for instruction: %bitreverse
+ %bitreverse = call <2 x i64> @llvm.bitreverse.v2i64(<2 x i64> %a)
+ ret <2 x i64> %bitreverse
+}
+
+define <4 x i64> @var_bitreverse_v4i64(<4 x i64> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bitreverse_v4i64':
+; SSE2: Found an estimated cost of 12 for instruction: %bitreverse
+; SSE42: Found an estimated cost of 10 for instruction: %bitreverse
+; AVX: Found an estimated cost of 10 for instruction: %bitreverse
+; AVX2: Found an estimated cost of 5 for instruction: %bitreverse
+; XOP: Found an estimated cost of 4 for instruction: %bitreverse
+ %bitreverse = call <4 x i64> @llvm.bitreverse.v4i64(<4 x i64> %a)
+ ret <4 x i64> %bitreverse
+}
+
+define <4 x i32> @var_bitreverse_v4i32(<4 x i32> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bitreverse_v4i32':
+; SSE2: Found an estimated cost of 12 for instruction: %bitreverse
+; SSE42: Found an estimated cost of 5 for instruction: %bitreverse
+; AVX: Found an estimated cost of 5 for instruction: %bitreverse
+; AVX2: Found an estimated cost of 5 for instruction: %bitreverse
+; XOP: Found an estimated cost of 1 for instruction: %bitreverse
+ %bitreverse = call <4 x i32> @llvm.bitreverse.v4i32(<4 x i32> %a)
+ ret <4 x i32> %bitreverse
+}
+
+define <8 x i32> @var_bitreverse_v8i32(<8 x i32> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bitreverse_v8i32':
+; SSE2: Found an estimated cost of 24 for instruction: %bitreverse
+; SSE42: Found an estimated cost of 10 for instruction: %bitreverse
+; AVX: Found an estimated cost of 10 for instruction: %bitreverse
+; AVX2: Found an estimated cost of 5 for instruction: %bitreverse
+; XOP: Found an estimated cost of 4 for instruction: %bitreverse
+ %bitreverse = call <8 x i32> @llvm.bitreverse.v8i32(<8 x i32> %a)
+ ret <8 x i32> %bitreverse
+}
+
+define <8 x i16> @var_bitreverse_v8i16(<8 x i16> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bitreverse_v8i16':
+; SSE2: Found an estimated cost of 24 for instruction: %bitreverse
+; SSE42: Found an estimated cost of 5 for instruction: %bitreverse
+; AVX: Found an estimated cost of 5 for instruction: %bitreverse
+; AVX2: Found an estimated cost of 5 for instruction: %bitreverse
+; XOP: Found an estimated cost of 1 for instruction: %bitreverse
+ %bitreverse = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %a)
+ ret <8 x i16> %bitreverse
+}
+
+define <16 x i16> @var_bitreverse_v16i16(<16 x i16> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bitreverse_v16i16':
+; SSE2: Found an estimated cost of 48 for instruction: %bitreverse
+; SSE42: Found an estimated cost of 10 for instruction: %bitreverse
+; AVX: Found an estimated cost of 10 for instruction: %bitreverse
+; AVX2: Found an estimated cost of 5 for instruction: %bitreverse
+; XOP: Found an estimated cost of 4 for instruction: %bitreverse
+ %bitreverse = call <16 x i16> @llvm.bitreverse.v16i16(<16 x i16> %a)
+ ret <16 x i16> %bitreverse
+}
+
+define <16 x i8> @var_bitreverse_v16i8(<16 x i8> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bitreverse_v16i8':
+; SSE2: Found an estimated cost of 48 for instruction: %bitreverse
+; SSE42: Found an estimated cost of 5 for instruction: %bitreverse
+; AVX: Found an estimated cost of 5 for instruction: %bitreverse
+; AVX2: Found an estimated cost of 5 for instruction: %bitreverse
+; XOP: Found an estimated cost of 1 for instruction: %bitreverse
+ %bitreverse = call <16 x i8> @llvm.bitreverse.v16i8(<16 x i8> %a)
+ ret <16 x i8> %bitreverse
+}
+
+define <32 x i8> @var_bitreverse_v32i8(<32 x i8> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bitreverse_v32i8':
+; SSE2: Found an estimated cost of 96 for instruction: %bitreverse
+; SSE42: Found an estimated cost of 10 for instruction: %bitreverse
+; AVX: Found an estimated cost of 10 for instruction: %bitreverse
+; AVX2: Found an estimated cost of 5 for instruction: %bitreverse
+; XOP: Found an estimated cost of 4 for instruction: %bitreverse
+ %bitreverse = call <32 x i8> @llvm.bitreverse.v32i8(<32 x i8> %a)
+ ret <32 x i8> %bitreverse
+}
diff --git a/test/Analysis/CostModel/X86/bswap.ll b/test/Analysis/CostModel/X86/bswap.ll
new file mode 100644
index 0000000000000..ecbe24c861cce
--- /dev/null
+++ b/test/Analysis/CostModel/X86/bswap.ll
@@ -0,0 +1,82 @@
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=pentium4 -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=SSE2
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=SSE42
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7-avx -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=AVX -check-prefix=AVX1
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=core-avx2 -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=AVX -check-prefix=AVX2
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=bdver2 -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=XOP -check-prefix=XOPAVX1
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=bdver4 -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=XOP -check-prefix=XOPAVX2
+
+; Verify the cost of vector bswap instructions.
+
+declare <2 x i64> @llvm.bswap.v2i64(<2 x i64>)
+declare <4 x i32> @llvm.bswap.v4i32(<4 x i32>)
+declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>)
+
+declare <4 x i64> @llvm.bswap.v4i64(<4 x i64>)
+declare <8 x i32> @llvm.bswap.v8i32(<8 x i32>)
+declare <16 x i16> @llvm.bswap.v16i16(<16 x i16>)
+
+define <2 x i64> @var_bswap_v2i64(<2 x i64> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bswap_v2i64':
+; SSE2: Found an estimated cost of 7 for instruction: %bswap
+; SSE42: Found an estimated cost of 1 for instruction: %bswap
+; AVX: Found an estimated cost of 1 for instruction: %bswap
+; XOP: Found an estimated cost of 1 for instruction: %bswap
+ %bswap = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> %a)
+ ret <2 x i64> %bswap
+}
+
+define <4 x i64> @var_bswap_v4i64(<4 x i64> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bswap_v4i64':
+; SSE2: Found an estimated cost of 14 for instruction: %bswap
+; SSE42: Found an estimated cost of 2 for instruction: %bswap
+; AVX1: Found an estimated cost of 4 for instruction: %bswap
+; AVX2: Found an estimated cost of 1 for instruction: %bswap
+; XOPAVX1: Found an estimated cost of 4 for instruction: %bswap
+; XOPAVX2: Found an estimated cost of 1 for instruction: %bswap
+ %bswap = call <4 x i64> @llvm.bswap.v4i64(<4 x i64> %a)
+ ret <4 x i64> %bswap
+}
+
+define <4 x i32> @var_bswap_v4i32(<4 x i32> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bswap_v4i32':
+; SSE2: Found an estimated cost of 7 for instruction: %bswap
+; SSE42: Found an estimated cost of 1 for instruction: %bswap
+; AVX: Found an estimated cost of 1 for instruction: %bswap
+; XOP: Found an estimated cost of 1 for instruction: %bswap
+ %bswap = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %a)
+ ret <4 x i32> %bswap
+}
+
+define <8 x i32> @var_bswap_v8i32(<8 x i32> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bswap_v8i32':
+; SSE2: Found an estimated cost of 14 for instruction: %bswap
+; SSE42: Found an estimated cost of 2 for instruction: %bswap
+; AVX1: Found an estimated cost of 4 for instruction: %bswap
+; AVX2: Found an estimated cost of 1 for instruction: %bswap
+; XOPAVX1: Found an estimated cost of 4 for instruction: %bswap
+; XOPAVX2: Found an estimated cost of 1 for instruction: %bswap
+ %bswap = call <8 x i32> @llvm.bswap.v8i32(<8 x i32> %a)
+ ret <8 x i32> %bswap
+}
+
+define <8 x i16> @var_bswap_v8i16(<8 x i16> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bswap_v8i16':
+; SSE2: Found an estimated cost of 7 for instruction: %bswap
+; SSE42: Found an estimated cost of 1 for instruction: %bswap
+; AVX: Found an estimated cost of 1 for instruction: %bswap
+; XOP: Found an estimated cost of 1 for instruction: %bswap
+ %bswap = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %a)
+ ret <8 x i16> %bswap
+}
+
+define <16 x i16> @var_bswap_v16i16(<16 x i16> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_bswap_v16i16':
+; SSE2: Found an estimated cost of 14 for instruction: %bswap
+; SSE42: Found an estimated cost of 2 for instruction: %bswap
+; AVX1: Found an estimated cost of 4 for instruction: %bswap
+; AVX2: Found an estimated cost of 1 for instruction: %bswap
+; XOPAVX1: Found an estimated cost of 4 for instruction: %bswap
+; XOPAVX2: Found an estimated cost of 1 for instruction: %bswap
+ %bswap = call <16 x i16> @llvm.bswap.v16i16(<16 x i16> %a)
+ ret <16 x i16> %bswap
+}
diff --git a/test/Analysis/CostModel/X86/cast.ll b/test/Analysis/CostModel/X86/cast.ll
index c518587c0e1ae..39e03c6c3b2f9 100644
--- a/test/Analysis/CostModel/X86/cast.ll
+++ b/test/Analysis/CostModel/X86/cast.ll
@@ -238,21 +238,21 @@ define void @uitofp8(<8 x i1> %a, <8 x i8> %b, <8 x i16> %c, <8 x i32> %d) {
define void @fp_conv(<8 x float> %a, <16 x float>%b, <4 x float> %c) {
;CHECK-LABEL: for function 'fp_conv'
- ; CHECK-AVX512: cost of 1 {{.*}} fpext
- %A1 = fpext <8 x float> %a to <8 x double>
+ ; CHECK: cost of 1 {{.*}} %A1 = fpext
+ %A1 = fpext <4 x float> %c to <4 x double>
- ; CHECK-AVX512: cost of 1 {{.*}} fpext
- %A2 = fpext <4 x float> %c to <4 x double>
+ ; CHECK-AVX: cost of 3 {{.*}} %A2 = fpext
+ ; CHECK-AVX2: cost of 3 {{.*}} %A2 = fpext
+ ; CHECK-AVX512: cost of 1 {{.*}} %A2 = fpext
+ %A2 = fpext <8 x float> %a to <8 x double>
- ; CHECK-AVX2: cost of 3 {{.*}} %A3 = fpext
- ; CHECK-AVX512: cost of 1 {{.*}} %A3 = fpext
- %A3 = fpext <8 x float> %a to <8 x double>
+ ; CHECK: cost of 1 {{.*}} %A3 = fptrunc
+ %A3 = fptrunc <4 x double> undef to <4 x float>
+ ; CHECK-AVX: cost of 3 {{.*}} %A4 = fptrunc
; CHECK-AVX2: cost of 3 {{.*}} %A4 = fptrunc
; CHECK-AVX512: cost of 1 {{.*}} %A4 = fptrunc
%A4 = fptrunc <8 x double> undef to <8 x float>
- ; CHECK-AVX512: cost of 1 {{.*}} %A5 = fptrunc
- %A5 = fptrunc <4 x double> undef to <4 x float>
ret void
}
diff --git a/test/Analysis/CostModel/X86/cmp.ll b/test/Analysis/CostModel/X86/cmp.ll
index 469cd735f8a01..f4733d6737e12 100644
--- a/test/Analysis/CostModel/X86/cmp.ll
+++ b/test/Analysis/CostModel/X86/cmp.ll
@@ -1,64 +1,144 @@
-; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx | FileCheck -check-prefix=CHECK -check-prefix=AVX1 %s
-; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=core-avx2 | FileCheck -check-prefix=CHECK -check-prefix=AVX2 %s
-; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=knl | FileCheck -check-prefix=CHECK -check-prefix=AVX512 %s
+; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=pentium4 | FileCheck --check-prefix=CHECK --check-prefix=SSE --check-prefix=SSE2 %s
+; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=yonah | FileCheck --check-prefix=CHECK --check-prefix=SSE --check-prefix=SSE3 %s
+; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=core2 | FileCheck --check-prefix=CHECK --check-prefix=SSE --check-prefix=SSSE3 %s
+; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=penryn | FileCheck --check-prefix=CHECK --check-prefix=SSE --check-prefix=SSE41 %s
+; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7 | FileCheck --check-prefix=CHECK --check-prefix=SSE --check-prefix=SSE42 %s
+; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx | FileCheck --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX1 %s
+; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=core-avx2 | FileCheck --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX2 %s
+; RUN: opt < %s -cost-model -analyze -mtriple=x86_64-apple-macosx10.8.0 -mcpu=knl | FileCheck --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX512 %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.8.0"
define i32 @cmp(i32 %arg) {
; -- floats --
- ;AVX1: cost of 1 {{.*}} fcmp
- ;AVX2: cost of 1 {{.*}} fcmp
+ ;SSE2: cost of 3 {{.*}} fcmp
+ ;SSE3: cost of 3 {{.*}} fcmp
+ ;SSSE3: cost of 3 {{.*}} fcmp
+ ;SSE41: cost of 3 {{.*}} fcmp
+ ;SSE42: cost of 1 {{.*}} fcmp
+ ;AVX: cost of 1 {{.*}} fcmp
%A = fcmp olt <2 x float> undef, undef
- ;AVX1: cost of 1 {{.*}} fcmp
- ;AVX2: cost of 1 {{.*}} fcmp
+
+ ;SSE2: cost of 7 {{.*}} fcmp
+ ;SSE3: cost of 7 {{.*}} fcmp
+ ;SSSE3: cost of 7 {{.*}} fcmp
+ ;SSE41: cost of 7 {{.*}} fcmp
+ ;SSE42: cost of 1 {{.*}} fcmp
+ ;AVX: cost of 1 {{.*}} fcmp
%B = fcmp olt <4 x float> undef, undef
- ;AVX1: cost of 1 {{.*}} fcmp
- ;AVX2: cost of 1 {{.*}} fcmp
+
+ ;SSE2: cost of 14 {{.*}} fcmp
+ ;SSE3: cost of 14 {{.*}} fcmp
+ ;SSSE3: cost of 14 {{.*}} fcmp
+ ;SSE41: cost of 14 {{.*}} fcmp
+ ;SSE42: cost of 2 {{.*}} fcmp
+ ;AVX: cost of 1 {{.*}} fcmp
%C = fcmp olt <8 x float> undef, undef
- ;AVX1: cost of 1 {{.*}} fcmp
- ;AVX2: cost of 1 {{.*}} fcmp
+
+ ;SSE2: cost of 3 {{.*}} fcmp
+ ;SSE3: cost of 3 {{.*}} fcmp
+ ;SSSE3: cost of 3 {{.*}} fcmp
+ ;SSE41: cost of 3 {{.*}} fcmp
+ ;SSE42: cost of 1 {{.*}} fcmp
+ ;AVX: cost of 1 {{.*}} fcmp
%D = fcmp olt <2 x double> undef, undef
- ;AVX1: cost of 1 {{.*}} fcmp
- ;AVX2: cost of 1 {{.*}} fcmp
+
+ ;SSE2: cost of 6 {{.*}} fcmp
+ ;SSE3: cost of 6 {{.*}} fcmp
+ ;SSSE3: cost of 6 {{.*}} fcmp
+ ;SSE41: cost of 6 {{.*}} fcmp
+ ;SSE42: cost of 2 {{.*}} fcmp
+ ;AVX: cost of 1 {{.*}} fcmp
%E = fcmp olt <4 x double> undef, undef
; AVX512: cost of 1 {{.*}} %E1 = fcmp
%E1 = fcmp olt <16 x float> undef, undef
- ; AVX512: cost of 2 {{.*}} %E2 = fcmp
- %E2 = fcmp olt <16 x double> undef, undef
+
+ ; AVX512: cost of 1 {{.*}} %E2 = fcmp
+ %E2 = fcmp olt <8 x double> undef, undef
+
+ ; AVX512: cost of 2 {{.*}} %E3 = fcmp
+ %E3 = fcmp olt <16 x double> undef, undef
; -- integers --
- ;AVX1: cost of 1 {{.*}} icmp
- ;AVX2: cost of 1 {{.*}} icmp
+ ;SSE2: cost of 1 {{.*}} icmp
+ ;SSE3: cost of 1 {{.*}} icmp
+ ;SSSE3: cost of 1 {{.*}} icmp
+ ;SSE41: cost of 1 {{.*}} icmp
+ ;SSE42: cost of 1 {{.*}} icmp
+ ;AVX: cost of 1 {{.*}} icmp
%F = icmp eq <16 x i8> undef, undef
- ;AVX1: cost of 1 {{.*}} icmp
- ;AVX2: cost of 1 {{.*}} icmp
+
+ ;SSE2: cost of 1 {{.*}} icmp
+ ;SSE3: cost of 1 {{.*}} icmp
+ ;SSSE3: cost of 1 {{.*}} icmp
+ ;SSE41: cost of 1 {{.*}} icmp
+ ;SSE42: cost of 1 {{.*}} icmp
+ ;AVX: cost of 1 {{.*}} icmp
%G = icmp eq <8 x i16> undef, undef
- ;AVX1: cost of 1 {{.*}} icmp
- ;AVX2: cost of 1 {{.*}} icmp
+
+ ;SSE2: cost of 1 {{.*}} icmp
+ ;SSE3: cost of 1 {{.*}} icmp
+ ;SSSE3: cost of 1 {{.*}} icmp
+ ;SSE41: cost of 1 {{.*}} icmp
+ ;SSE42: cost of 1 {{.*}} icmp
+ ;AVX: cost of 1 {{.*}} icmp
%H = icmp eq <4 x i32> undef, undef
- ;AVX1: cost of 1 {{.*}} icmp
- ;AVX2: cost of 1 {{.*}} icmp
+
+ ;SSE2: cost of 8 {{.*}} icmp
+ ;SSE3: cost of 8 {{.*}} icmp
+ ;SSSE3: cost of 8 {{.*}} icmp
+ ;SSE41: cost of 8 {{.*}} icmp
+ ;SSE42: cost of 1 {{.*}} icmp
+ ;AVX: cost of 1 {{.*}} icmp
%I = icmp eq <2 x i64> undef, undef
- ;AVX1: cost of 4 {{.*}} icmp
- ;AVX2: cost of 1 {{.*}} icmp
+
+ ;SSE2: cost of 16 {{.*}} icmp
+ ;SSE3: cost of 16 {{.*}} icmp
+ ;SSSE3: cost of 16 {{.*}} icmp
+ ;SSE41: cost of 16 {{.*}} icmp
+ ;SSE42: cost of 2 {{.*}} icmp
+ ;AVX1: cost of 4 {{.*}} icmp
+ ;AVX2: cost of 1 {{.*}} icmp
%J = icmp eq <4 x i64> undef, undef
- ;AVX1: cost of 4 {{.*}} icmp
- ;AVX2: cost of 1 {{.*}} icmp
+
+ ;SSE2: cost of 2 {{.*}} icmp
+ ;SSE3: cost of 2 {{.*}} icmp
+ ;SSSE3: cost of 2 {{.*}} icmp
+ ;SSE41: cost of 2 {{.*}} icmp
+ ;SSE42: cost of 2 {{.*}} icmp
+ ;AVX1: cost of 4 {{.*}} icmp
+ ;AVX2: cost of 1 {{.*}} icmp
%K = icmp eq <8 x i32> undef, undef
- ;AVX1: cost of 4 {{.*}} icmp
- ;AVX2: cost of 1 {{.*}} icmp
+
+ ;SSE2: cost of 2 {{.*}} icmp
+ ;SSE3: cost of 2 {{.*}} icmp
+ ;SSSE3: cost of 2 {{.*}} icmp
+ ;SSE41: cost of 2 {{.*}} icmp
+ ;SSE42: cost of 2 {{.*}} icmp
+ ;AVX1: cost of 4 {{.*}} icmp
+ ;AVX2: cost of 1 {{.*}} icmp
%L = icmp eq <16 x i16> undef, undef
- ;AVX1: cost of 4 {{.*}} icmp
- ;AVX2: cost of 1 {{.*}} icmp
+
+ ;SSE2: cost of 2 {{.*}} icmp
+ ;SSE3: cost of 2 {{.*}} icmp
+ ;SSSE3: cost of 2 {{.*}} icmp
+ ;SSE41: cost of 2 {{.*}} icmp
+ ;SSE42: cost of 2 {{.*}} icmp
+ ;AVX1: cost of 4 {{.*}} icmp
+ ;AVX2: cost of 1 {{.*}} icmp
%M = icmp eq <32 x i8> undef, undef
; AVX512: cost of 1 {{.*}} %M1 = icmp
%M1 = icmp eq <16 x i32> undef, undef
- ; AVX512: cost of 2 {{.*}} %M2 = icmp
- %M2 = icmp eq <16 x i64> undef, undef
+
+ ; AVX512: cost of 1 {{.*}} %M2 = icmp
+ %M2 = icmp eq <8 x i64> undef, undef
+
+ ; AVX512: cost of 2 {{.*}} %M3 = icmp
+ %M3 = icmp eq <16 x i64> undef, undef
;CHECK: cost of 0 {{.*}} ret
ret i32 undef
diff --git a/test/Analysis/CostModel/X86/ctbits-cost.ll b/test/Analysis/CostModel/X86/ctbits-cost.ll
new file mode 100644
index 0000000000000..23bfafd8bc945
--- /dev/null
+++ b/test/Analysis/CostModel/X86/ctbits-cost.ll
@@ -0,0 +1,567 @@
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=pentium4 -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=SSE -check-prefix=SSE2 -check-prefix=NOPOPCNT
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=SSE -check-prefix=SSE42 -check-prefix=POPCNT
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7-avx -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=AVX -check-prefix=AVX1 -check-prefix=POPCNT
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=core-avx2 -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=AVX -check-prefix=AVX2 -check-prefix=POPCNT
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=bdver2 -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=XOP -check-prefix=XOPAVX1 -check-prefix=POPCNT
+; RUN: opt < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=bdver4 -cost-model -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=XOP -check-prefix=XOPAVX2 -check-prefix=POPCNT
+
+; Verify the cost of scalar population count instructions.
+
+declare i64 @llvm.ctpop.i64(i64)
+declare i32 @llvm.ctpop.i32(i32)
+declare i16 @llvm.ctpop.i16(i16)
+declare i8 @llvm.ctpop.i8(i8)
+
+define i64 @var_ctpop_i64(i64 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctpop_i64':
+; NOPOPCNT: Found an estimated cost of 4 for instruction: %ctpop
+; POPCNT: Found an estimated cost of 1 for instruction: %ctpop
+ %ctpop = call i64 @llvm.ctpop.i64(i64 %a)
+ ret i64 %ctpop
+}
+
+define i32 @var_ctpop_i32(i32 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctpop_i32':
+; NOPOPCNT: Found an estimated cost of 4 for instruction: %ctpop
+; POPCNT: Found an estimated cost of 1 for instruction: %ctpop
+ %ctpop = call i32 @llvm.ctpop.i32(i32 %a)
+ ret i32 %ctpop
+}
+
+define i16 @var_ctpop_i16(i16 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctpop_i16':
+; NOPOPCNT: Found an estimated cost of 4 for instruction: %ctpop
+; POPCNT: Found an estimated cost of 1 for instruction: %ctpop
+ %ctpop = call i16 @llvm.ctpop.i16(i16 %a)
+ ret i16 %ctpop
+}
+
+define i8 @var_ctpop_i8(i8 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctpop_i8':
+; NOPOPCNT: Found an estimated cost of 4 for instruction: %ctpop
+; POPCNT: Found an estimated cost of 1 for instruction: %ctpop
+ %ctpop = call i8 @llvm.ctpop.i8(i8 %a)
+ ret i8 %ctpop
+}
+
+; Verify the cost of vector population count instructions.
+
+declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>)
+declare <4 x i32> @llvm.ctpop.v4i32(<4 x i32>)
+declare <8 x i16> @llvm.ctpop.v8i16(<8 x i16>)
+declare <16 x i8> @llvm.ctpop.v16i8(<16 x i8>)
+
+declare <4 x i64> @llvm.ctpop.v4i64(<4 x i64>)
+declare <8 x i32> @llvm.ctpop.v8i32(<8 x i32>)
+declare <16 x i16> @llvm.ctpop.v16i16(<16 x i16>)
+declare <32 x i8> @llvm.ctpop.v32i8(<32 x i8>)
+
+define <2 x i64> @var_ctpop_v2i64(<2 x i64> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctpop_v2i64':
+; SSE: Found an estimated cost of 2 for instruction: %ctpop
+; AVX: Found an estimated cost of 2 for instruction: %ctpop
+; XOP: Found an estimated cost of 2 for instruction: %ctpop
+ %ctpop = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
+ ret <2 x i64> %ctpop
+}
+
+define <4 x i64> @var_ctpop_v4i64(<4 x i64> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctpop_v4i64':
+; SSE: Found an estimated cost of 4 for instruction: %ctpop
+; AVX: Found an estimated cost of 2 for instruction: %ctpop
+; XOP: Found an estimated cost of 2 for instruction: %ctpop
+ %ctpop = call <4 x i64> @llvm.ctpop.v4i64(<4 x i64> %a)
+ ret <4 x i64> %ctpop
+}
+
+define <4 x i32> @var_ctpop_v4i32(<4 x i32> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctpop_v4i32':
+; SSE: Found an estimated cost of 2 for instruction: %ctpop
+; AVX: Found an estimated cost of 2 for instruction: %ctpop
+; XOP: Found an estimated cost of 2 for instruction: %ctpop
+ %ctpop = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %a)
+ ret <4 x i32> %ctpop
+}
+
+define <8 x i32> @var_ctpop_v8i32(<8 x i32> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctpop_v8i32':
+; SSE: Found an estimated cost of 4 for instruction: %ctpop
+; AVX: Found an estimated cost of 2 for instruction: %ctpop
+; XOP: Found an estimated cost of 2 for instruction: %ctpop
+ %ctpop = call <8 x i32> @llvm.ctpop.v8i32(<8 x i32> %a)
+ ret <8 x i32> %ctpop
+}
+
+define <8 x i16> @var_ctpop_v8i16(<8 x i16> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctpop_v8i16':
+; SSE: Found an estimated cost of 2 for instruction: %ctpop
+; AVX: Found an estimated cost of 2 for instruction: %ctpop
+; XOP: Found an estimated cost of 2 for instruction: %ctpop
+ %ctpop = call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %a)
+ ret <8 x i16> %ctpop
+}
+
+define <16 x i16> @var_ctpop_v16i16(<16 x i16> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctpop_v16i16':
+; SSE: Found an estimated cost of 4 for instruction: %ctpop
+; AVX: Found an estimated cost of 2 for instruction: %ctpop
+; XOP: Found an estimated cost of 2 for instruction: %ctpop
+ %ctpop = call <16 x i16> @llvm.ctpop.v16i16(<16 x i16> %a)
+ ret <16 x i16> %ctpop
+}
+
+define <16 x i8> @var_ctpop_v16i8(<16 x i8> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctpop_v16i8':
+; SSE: Found an estimated cost of 2 for instruction: %ctpop
+; AVX: Found an estimated cost of 2 for instruction: %ctpop
+; XOP: Found an estimated cost of 2 for instruction: %ctpop
+ %ctpop = call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %a)
+ ret <16 x i8> %ctpop
+}
+
+define <32 x i8> @var_ctpop_v32i8(<32 x i8> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctpop_v32i8':
+; SSE: Found an estimated cost of 4 for instruction: %ctpop
+; AVX: Found an estimated cost of 2 for instruction: %ctpop
+; XOP: Found an estimated cost of 2 for instruction: %ctpop
+ %ctpop = call <32 x i8> @llvm.ctpop.v32i8(<32 x i8> %a)
+ ret <32 x i8> %ctpop
+}
+
+; Verify the cost of scalar leading zero count instructions.
+
+declare i64 @llvm.ctlz.i64(i64, i1)
+declare i32 @llvm.ctlz.i32(i32, i1)
+declare i16 @llvm.ctlz.i16(i16, i1)
+declare i8 @llvm.ctlz.i8(i8, i1)
+
+define i64 @var_ctlz_i64(i64 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_i64':
+; CHECK: Found an estimated cost of 1 for instruction: %ctlz
+ %ctlz = call i64 @llvm.ctlz.i64(i64 %a, i1 0)
+ ret i64 %ctlz
+}
+
+define i64 @var_ctlz_i64u(i64 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_i64u':
+; CHECK: Found an estimated cost of 1 for instruction: %ctlz
+ %ctlz = call i64 @llvm.ctlz.i64(i64 %a, i1 1)
+ ret i64 %ctlz
+}
+
+define i32 @var_ctlz_i32(i32 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_i32':
+; CHECK: Found an estimated cost of 1 for instruction: %ctlz
+ %ctlz = call i32 @llvm.ctlz.i32(i32 %a, i1 0)
+ ret i32 %ctlz
+}
+
+define i32 @var_ctlz_i32u(i32 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_i32u':
+; CHECK: Found an estimated cost of 1 for instruction: %ctlz
+ %ctlz = call i32 @llvm.ctlz.i32(i32 %a, i1 1)
+ ret i32 %ctlz
+}
+
+define i16 @var_ctlz_i16(i16 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_i16':
+; CHECK: Found an estimated cost of 1 for instruction: %ctlz
+ %ctlz = call i16 @llvm.ctlz.i16(i16 %a, i1 0)
+ ret i16 %ctlz
+}
+
+define i16 @var_ctlz_i16u(i16 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_i16u':
+; CHECK: Found an estimated cost of 1 for instruction: %ctlz
+ %ctlz = call i16 @llvm.ctlz.i16(i16 %a, i1 1)
+ ret i16 %ctlz
+}
+
+define i8 @var_ctlz_i8(i8 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_i8':
+; CHECK: Found an estimated cost of 1 for instruction: %ctlz
+ %ctlz = call i8 @llvm.ctlz.i8(i8 %a, i1 0)
+ ret i8 %ctlz
+}
+
+define i8 @var_ctlz_i8u(i8 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_i8u':
+; CHECK: Found an estimated cost of 1 for instruction: %ctlz
+ %ctlz = call i8 @llvm.ctlz.i8(i8 %a, i1 1)
+ ret i8 %ctlz
+}
+
+; Verify the cost of vector leading zero count instructions.
+
+declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>, i1)
+declare <4 x i32> @llvm.ctlz.v4i32(<4 x i32>, i1)
+declare <8 x i16> @llvm.ctlz.v8i16(<8 x i16>, i1)
+declare <16 x i8> @llvm.ctlz.v16i8(<16 x i8>, i1)
+
+declare <4 x i64> @llvm.ctlz.v4i64(<4 x i64>, i1)
+declare <8 x i32> @llvm.ctlz.v8i32(<8 x i32>, i1)
+declare <16 x i16> @llvm.ctlz.v16i16(<16 x i16>, i1)
+declare <32 x i8> @llvm.ctlz.v32i8(<32 x i8>, i1)
+
+define <2 x i64> @var_ctlz_v2i64(<2 x i64> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v2i64':
+; SSE: Found an estimated cost of 6 for instruction: %ctlz
+; AVX: Found an estimated cost of 6 for instruction: %ctlz
+; XOP: Found an estimated cost of 6 for instruction: %ctlz
+ %ctlz = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %a, i1 0)
+ ret <2 x i64> %ctlz
+}
+
+define <2 x i64> @var_ctlz_v2i64u(<2 x i64> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v2i64u':
+; SSE: Found an estimated cost of 6 for instruction: %ctlz
+; AVX: Found an estimated cost of 6 for instruction: %ctlz
+; XOP: Found an estimated cost of 6 for instruction: %ctlz
+ %ctlz = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %a, i1 1)
+ ret <2 x i64> %ctlz
+}
+
+define <4 x i64> @var_ctlz_v4i64(<4 x i64> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v4i64':
+; SSE: Found an estimated cost of 12 for instruction: %ctlz
+; AVX: Found an estimated cost of 12 for instruction: %ctlz
+; XOP: Found an estimated cost of 12 for instruction: %ctlz
+ %ctlz = call <4 x i64> @llvm.ctlz.v4i64(<4 x i64> %a, i1 0)
+ ret <4 x i64> %ctlz
+}
+
+define <4 x i64> @var_ctlz_v4i64u(<4 x i64> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v4i64u':
+; SSE: Found an estimated cost of 12 for instruction: %ctlz
+; AVX: Found an estimated cost of 12 for instruction: %ctlz
+; XOP: Found an estimated cost of 12 for instruction: %ctlz
+ %ctlz = call <4 x i64> @llvm.ctlz.v4i64(<4 x i64> %a, i1 1)
+ ret <4 x i64> %ctlz
+}
+
+define <4 x i32> @var_ctlz_v4i32(<4 x i32> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v4i32':
+; SSE: Found an estimated cost of 12 for instruction: %ctlz
+; AVX: Found an estimated cost of 12 for instruction: %ctlz
+; XOP: Found an estimated cost of 12 for instruction: %ctlz
+ %ctlz = call <4 x i32> @llvm.ctlz.v4i32(<4 x i32> %a, i1 0)
+ ret <4 x i32> %ctlz
+}
+
+define <4 x i32> @var_ctlz_v4i32u(<4 x i32> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v4i32u':
+; SSE: Found an estimated cost of 12 for instruction: %ctlz
+; AVX: Found an estimated cost of 12 for instruction: %ctlz
+; XOP: Found an estimated cost of 12 for instruction: %ctlz
+ %ctlz = call <4 x i32> @llvm.ctlz.v4i32(<4 x i32> %a, i1 1)
+ ret <4 x i32> %ctlz
+}
+
+define <8 x i32> @var_ctlz_v8i32(<8 x i32> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v8i32':
+; SSE: Found an estimated cost of 24 for instruction: %ctlz
+; AVX: Found an estimated cost of 24 for instruction: %ctlz
+; XOP: Found an estimated cost of 24 for instruction: %ctlz
+ %ctlz = call <8 x i32> @llvm.ctlz.v8i32(<8 x i32> %a, i1 0)
+ ret <8 x i32> %ctlz
+}
+
+define <8 x i32> @var_ctlz_v8i32u(<8 x i32> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v8i32u':
+; SSE: Found an estimated cost of 24 for instruction: %ctlz
+; AVX: Found an estimated cost of 24 for instruction: %ctlz
+; XOP: Found an estimated cost of 24 for instruction: %ctlz
+ %ctlz = call <8 x i32> @llvm.ctlz.v8i32(<8 x i32> %a, i1 1)
+ ret <8 x i32> %ctlz
+}
+
+define <8 x i16> @var_ctlz_v8i16(<8 x i16> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v8i16':
+; SSE: Found an estimated cost of 24 for instruction: %ctlz
+; AVX: Found an estimated cost of 24 for instruction: %ctlz
+; XOP: Found an estimated cost of 24 for instruction: %ctlz
+ %ctlz = call <8 x i16> @llvm.ctlz.v8i16(<8 x i16> %a, i1 0)
+ ret <8 x i16> %ctlz
+}
+
+define <8 x i16> @var_ctlz_v8i16u(<8 x i16> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v8i16u':
+; SSE: Found an estimated cost of 24 for instruction: %ctlz
+; AVX: Found an estimated cost of 24 for instruction: %ctlz
+; XOP: Found an estimated cost of 24 for instruction: %ctlz
+ %ctlz = call <8 x i16> @llvm.ctlz.v8i16(<8 x i16> %a, i1 1)
+ ret <8 x i16> %ctlz
+}
+
+define <16 x i16> @var_ctlz_v16i16(<16 x i16> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v16i16':
+; SSE: Found an estimated cost of 48 for instruction: %ctlz
+; AVX: Found an estimated cost of 48 for instruction: %ctlz
+; XOP: Found an estimated cost of 48 for instruction: %ctlz
+ %ctlz = call <16 x i16> @llvm.ctlz.v16i16(<16 x i16> %a, i1 0)
+ ret <16 x i16> %ctlz
+}
+
+define <16 x i16> @var_ctlz_v16i16u(<16 x i16> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v16i16u':
+; SSE: Found an estimated cost of 48 for instruction: %ctlz
+; AVX: Found an estimated cost of 48 for instruction: %ctlz
+; XOP: Found an estimated cost of 48 for instruction: %ctlz
+ %ctlz = call <16 x i16> @llvm.ctlz.v16i16(<16 x i16> %a, i1 1)
+ ret <16 x i16> %ctlz
+}
+
+define <16 x i8> @var_ctlz_v16i8(<16 x i8> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v16i8':
+; SSE: Found an estimated cost of 48 for instruction: %ctlz
+; AVX: Found an estimated cost of 48 for instruction: %ctlz
+; XOP: Found an estimated cost of 48 for instruction: %ctlz
+ %ctlz = call <16 x i8> @llvm.ctlz.v16i8(<16 x i8> %a, i1 0)
+ ret <16 x i8> %ctlz
+}
+
+define <16 x i8> @var_ctlz_v16i8u(<16 x i8> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v16i8u':
+; SSE: Found an estimated cost of 48 for instruction: %ctlz
+; AVX: Found an estimated cost of 48 for instruction: %ctlz
+; XOP: Found an estimated cost of 48 for instruction: %ctlz
+ %ctlz = call <16 x i8> @llvm.ctlz.v16i8(<16 x i8> %a, i1 1)
+ ret <16 x i8> %ctlz
+}
+
+define <32 x i8> @var_ctlz_v32i8(<32 x i8> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v32i8':
+; SSE: Found an estimated cost of 96 for instruction: %ctlz
+; AVX: Found an estimated cost of 96 for instruction: %ctlz
+; XOP: Found an estimated cost of 96 for instruction: %ctlz
+ %ctlz = call <32 x i8> @llvm.ctlz.v32i8(<32 x i8> %a, i1 0)
+ ret <32 x i8> %ctlz
+}
+
+define <32 x i8> @var_ctlz_v32i8u(<32 x i8> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_ctlz_v32i8u':
+; SSE: Found an estimated cost of 96 for instruction: %ctlz
+; AVX: Found an estimated cost of 96 for instruction: %ctlz
+; XOP: Found an estimated cost of 96 for instruction: %ctlz
+ %ctlz = call <32 x i8> @llvm.ctlz.v32i8(<32 x i8> %a, i1 1)
+ ret <32 x i8> %ctlz
+}
+
+; Verify the cost of scalar trailing zero count instructions.
+
+declare i64 @llvm.cttz.i64(i64, i1)
+declare i32 @llvm.cttz.i32(i32, i1)
+declare i16 @llvm.cttz.i16(i16, i1)
+declare i8 @llvm.cttz.i8(i8, i1)
+
+define i64 @var_cttz_i64(i64 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_i64':
+; CHECK: Found an estimated cost of 1 for instruction: %cttz
+ %cttz = call i64 @llvm.cttz.i64(i64 %a, i1 0)
+ ret i64 %cttz
+}
+
+define i64 @var_cttz_i64u(i64 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_i64u':
+; CHECK: Found an estimated cost of 1 for instruction: %cttz
+ %cttz = call i64 @llvm.cttz.i64(i64 %a, i1 1)
+ ret i64 %cttz
+}
+
+define i32 @var_cttz_i32(i32 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_i32':
+; CHECK: Found an estimated cost of 1 for instruction: %cttz
+ %cttz = call i32 @llvm.cttz.i32(i32 %a, i1 0)
+ ret i32 %cttz
+}
+
+define i32 @var_cttz_i32u(i32 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_i32u':
+; CHECK: Found an estimated cost of 1 for instruction: %cttz
+ %cttz = call i32 @llvm.cttz.i32(i32 %a, i1 1)
+ ret i32 %cttz
+}
+
+define i16 @var_cttz_i16(i16 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_i16':
+; CHECK: Found an estimated cost of 1 for instruction: %cttz
+ %cttz = call i16 @llvm.cttz.i16(i16 %a, i1 0)
+ ret i16 %cttz
+}
+
+define i16 @var_cttz_i16u(i16 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_i16u':
+; CHECK: Found an estimated cost of 1 for instruction: %cttz
+ %cttz = call i16 @llvm.cttz.i16(i16 %a, i1 1)
+ ret i16 %cttz
+}
+
+define i8 @var_cttz_i8(i8 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_i8':
+; CHECK: Found an estimated cost of 1 for instruction: %cttz
+ %cttz = call i8 @llvm.cttz.i8(i8 %a, i1 0)
+ ret i8 %cttz
+}
+
+define i8 @var_cttz_i8u(i8 %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_i8u':
+; CHECK: Found an estimated cost of 1 for instruction: %cttz
+ %cttz = call i8 @llvm.cttz.i8(i8 %a, i1 1)
+ ret i8 %cttz
+}
+
+; Verify the cost of vector trailing zero count instructions.
+
+declare <2 x i64> @llvm.cttz.v2i64(<2 x i64>, i1)
+declare <4 x i32> @llvm.cttz.v4i32(<4 x i32>, i1)
+declare <8 x i16> @llvm.cttz.v8i16(<8 x i16>, i1)
+declare <16 x i8> @llvm.cttz.v16i8(<16 x i8>, i1)
+
+declare <4 x i64> @llvm.cttz.v4i64(<4 x i64>, i1)
+declare <8 x i32> @llvm.cttz.v8i32(<8 x i32>, i1)
+declare <16 x i16> @llvm.cttz.v16i16(<16 x i16>, i1)
+declare <32 x i8> @llvm.cttz.v32i8(<32 x i8>, i1)
+
+define <2 x i64> @var_cttz_v2i64(<2 x i64> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v2i64':
+; SSE: Found an estimated cost of 6 for instruction: %cttz
+; AVX: Found an estimated cost of 6 for instruction: %cttz
+; XOP: Found an estimated cost of 6 for instruction: %cttz
+ %cttz = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %a, i1 0)
+ ret <2 x i64> %cttz
+}
+
+define <2 x i64> @var_cttz_v2i64u(<2 x i64> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v2i64u':
+; SSE: Found an estimated cost of 6 for instruction: %cttz
+; AVX: Found an estimated cost of 6 for instruction: %cttz
+; XOP: Found an estimated cost of 6 for instruction: %cttz
+ %cttz = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %a, i1 1)
+ ret <2 x i64> %cttz
+}
+
+define <4 x i64> @var_cttz_v4i64(<4 x i64> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v4i64':
+; SSE: Found an estimated cost of 12 for instruction: %cttz
+; AVX: Found an estimated cost of 12 for instruction: %cttz
+; XOP: Found an estimated cost of 12 for instruction: %cttz
+ %cttz = call <4 x i64> @llvm.cttz.v4i64(<4 x i64> %a, i1 0)
+ ret <4 x i64> %cttz
+}
+
+define <4 x i64> @var_cttz_v4i64u(<4 x i64> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v4i64u':
+; SSE: Found an estimated cost of 12 for instruction: %cttz
+; AVX: Found an estimated cost of 12 for instruction: %cttz
+; XOP: Found an estimated cost of 12 for instruction: %cttz
+ %cttz = call <4 x i64> @llvm.cttz.v4i64(<4 x i64> %a, i1 1)
+ ret <4 x i64> %cttz
+}
+
+define <4 x i32> @var_cttz_v4i32(<4 x i32> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v4i32':
+; SSE: Found an estimated cost of 12 for instruction: %cttz
+; AVX: Found an estimated cost of 12 for instruction: %cttz
+; XOP: Found an estimated cost of 12 for instruction: %cttz
+ %cttz = call <4 x i32> @llvm.cttz.v4i32(<4 x i32> %a, i1 0)
+ ret <4 x i32> %cttz
+}
+
+define <4 x i32> @var_cttz_v4i32u(<4 x i32> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v4i32u':
+; SSE: Found an estimated cost of 12 for instruction: %cttz
+; AVX: Found an estimated cost of 12 for instruction: %cttz
+; XOP: Found an estimated cost of 12 for instruction: %cttz
+ %cttz = call <4 x i32> @llvm.cttz.v4i32(<4 x i32> %a, i1 1)
+ ret <4 x i32> %cttz
+}
+
+define <8 x i32> @var_cttz_v8i32(<8 x i32> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v8i32':
+; SSE: Found an estimated cost of 24 for instruction: %cttz
+; AVX: Found an estimated cost of 24 for instruction: %cttz
+; XOP: Found an estimated cost of 24 for instruction: %cttz
+ %cttz = call <8 x i32> @llvm.cttz.v8i32(<8 x i32> %a, i1 0)
+ ret <8 x i32> %cttz
+}
+
+define <8 x i32> @var_cttz_v8i32u(<8 x i32> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v8i32u':
+; SSE: Found an estimated cost of 24 for instruction: %cttz
+; AVX: Found an estimated cost of 24 for instruction: %cttz
+; XOP: Found an estimated cost of 24 for instruction: %cttz
+ %cttz = call <8 x i32> @llvm.cttz.v8i32(<8 x i32> %a, i1 1)
+ ret <8 x i32> %cttz
+}
+
+define <8 x i16> @var_cttz_v8i16(<8 x i16> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v8i16':
+; SSE: Found an estimated cost of 24 for instruction: %cttz
+; AVX: Found an estimated cost of 24 for instruction: %cttz
+; XOP: Found an estimated cost of 24 for instruction: %cttz
+ %cttz = call <8 x i16> @llvm.cttz.v8i16(<8 x i16> %a, i1 0)
+ ret <8 x i16> %cttz
+}
+
+define <8 x i16> @var_cttz_v8i16u(<8 x i16> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v8i16u':
+; SSE: Found an estimated cost of 24 for instruction: %cttz
+; AVX: Found an estimated cost of 24 for instruction: %cttz
+; XOP: Found an estimated cost of 24 for instruction: %cttz
+ %cttz = call <8 x i16> @llvm.cttz.v8i16(<8 x i16> %a, i1 1)
+ ret <8 x i16> %cttz
+}
+
+define <16 x i16> @var_cttz_v16i16(<16 x i16> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v16i16':
+; SSE: Found an estimated cost of 48 for instruction: %cttz
+; AVX: Found an estimated cost of 48 for instruction: %cttz
+; XOP: Found an estimated cost of 48 for instruction: %cttz
+ %cttz = call <16 x i16> @llvm.cttz.v16i16(<16 x i16> %a, i1 0)
+ ret <16 x i16> %cttz
+}
+
+define <16 x i16> @var_cttz_v16i16u(<16 x i16> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v16i16u':
+; SSE: Found an estimated cost of 48 for instruction: %cttz
+; AVX: Found an estimated cost of 48 for instruction: %cttz
+; XOP: Found an estimated cost of 48 for instruction: %cttz
+ %cttz = call <16 x i16> @llvm.cttz.v16i16(<16 x i16> %a, i1 1)
+ ret <16 x i16> %cttz
+}
+
+define <16 x i8> @var_cttz_v16i8(<16 x i8> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v16i8':
+; SSE: Found an estimated cost of 48 for instruction: %cttz
+; AVX: Found an estimated cost of 48 for instruction: %cttz
+; XOP: Found an estimated cost of 48 for instruction: %cttz
+ %cttz = call <16 x i8> @llvm.cttz.v16i8(<16 x i8> %a, i1 0)
+ ret <16 x i8> %cttz
+}
+
+define <16 x i8> @var_cttz_v16i8u(<16 x i8> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v16i8u':
+; SSE: Found an estimated cost of 48 for instruction: %cttz
+; AVX: Found an estimated cost of 48 for instruction: %cttz
+; XOP: Found an estimated cost of 48 for instruction: %cttz
+ %cttz = call <16 x i8> @llvm.cttz.v16i8(<16 x i8> %a, i1 1)
+ ret <16 x i8> %cttz
+}
+
+define <32 x i8> @var_cttz_v32i8(<32 x i8> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v32i8':
+; SSE: Found an estimated cost of 96 for instruction: %cttz
+; AVX: Found an estimated cost of 96 for instruction: %cttz
+; XOP: Found an estimated cost of 96 for instruction: %cttz
+ %cttz = call <32 x i8> @llvm.cttz.v32i8(<32 x i8> %a, i1 0)
+ ret <32 x i8> %cttz
+}
+
+define <32 x i8> @var_cttz_v32i8u(<32 x i8> %a) {
+; CHECK: 'Cost Model Analysis' for function 'var_cttz_v32i8u':
+; SSE: Found an estimated cost of 96 for instruction: %cttz
+; AVX: Found an estimated cost of 96 for instruction: %cttz
+; XOP: Found an estimated cost of 96 for instruction: %cttz
+ %cttz = call <32 x i8> @llvm.cttz.v32i8(<32 x i8> %a, i1 1)
+ ret <32 x i8> %cttz
+}
diff --git a/test/Analysis/CostModel/X86/masked-intrinsic-cost.ll b/test/Analysis/CostModel/X86/masked-intrinsic-cost.ll
index 61d3e0116e8b4..f2d3f3f0ce639 100644
--- a/test/Analysis/CostModel/X86/masked-intrinsic-cost.ll
+++ b/test/Analysis/CostModel/X86/masked-intrinsic-cost.ll
@@ -7,7 +7,7 @@
; AVX2: Found an estimated cost of 4 {{.*}}.masked
define <2 x double> @test1(<2 x i64> %trigger, <2 x double>* %addr, <2 x double> %dst) {
%mask = icmp eq <2 x i64> %trigger, zeroinitializer
- %res = call <2 x double> @llvm.masked.load.v2f64(<2 x double>* %addr, i32 4, <2 x i1>%mask, <2 x double>%dst)
+ %res = call <2 x double> @llvm.masked.load.v2f64.p0v2f64(<2 x double>* %addr, i32 4, <2 x i1>%mask, <2 x double>%dst)
ret <2 x double> %res
}
@@ -15,7 +15,7 @@ define <2 x double> @test1(<2 x i64> %trigger, <2 x double>* %addr, <2 x double>
; AVX2: Found an estimated cost of 4 {{.*}}.masked
define <4 x i32> @test2(<4 x i32> %trigger, <4 x i32>* %addr, <4 x i32> %dst) {
%mask = icmp eq <4 x i32> %trigger, zeroinitializer
- %res = call <4 x i32> @llvm.masked.load.v4i32(<4 x i32>* %addr, i32 4, <4 x i1>%mask, <4 x i32>%dst)
+ %res = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %addr, i32 4, <4 x i1>%mask, <4 x i32>%dst)
ret <4 x i32> %res
}
@@ -23,7 +23,7 @@ define <4 x i32> @test2(<4 x i32> %trigger, <4 x i32>* %addr, <4 x i32> %dst) {
; AVX2: Found an estimated cost of 4 {{.*}}.masked
define void @test3(<4 x i32> %trigger, <4 x i32>* %addr, <4 x i32> %val) {
%mask = icmp eq <4 x i32> %trigger, zeroinitializer
- call void @llvm.masked.store.v4i32(<4 x i32>%val, <4 x i32>* %addr, i32 4, <4 x i1>%mask)
+ call void @llvm.masked.store.v4i32.p0v4i32(<4 x i32>%val, <4 x i32>* %addr, i32 4, <4 x i1>%mask)
ret void
}
@@ -31,7 +31,7 @@ define void @test3(<4 x i32> %trigger, <4 x i32>* %addr, <4 x i32> %val) {
; AVX2: Found an estimated cost of 4 {{.*}}.masked
define <8 x float> @test4(<8 x i32> %trigger, <8 x float>* %addr, <8 x float> %dst) {
%mask = icmp eq <8 x i32> %trigger, zeroinitializer
- %res = call <8 x float> @llvm.masked.load.v8f32(<8 x float>* %addr, i32 4, <8 x i1>%mask, <8 x float>%dst)
+ %res = call <8 x float> @llvm.masked.load.v8f32.p0v8f32(<8 x float>* %addr, i32 4, <8 x i1>%mask, <8 x float>%dst)
ret <8 x float> %res
}
@@ -39,7 +39,7 @@ define <8 x float> @test4(<8 x i32> %trigger, <8 x float>* %addr, <8 x float> %d
; AVX2: Found an estimated cost of 5 {{.*}}.masked
define void @test5(<2 x i32> %trigger, <2 x float>* %addr, <2 x float> %val) {
%mask = icmp eq <2 x i32> %trigger, zeroinitializer
- call void @llvm.masked.store.v2f32(<2 x float>%val, <2 x float>* %addr, i32 4, <2 x i1>%mask)
+ call void @llvm.masked.store.v2f32.p0v2f32(<2 x float>%val, <2 x float>* %addr, i32 4, <2 x i1>%mask)
ret void
}
@@ -47,7 +47,7 @@ define void @test5(<2 x i32> %trigger, <2 x float>* %addr, <2 x float> %val) {
; AVX2: Found an estimated cost of 6 {{.*}}.masked
define void @test6(<2 x i32> %trigger, <2 x i32>* %addr, <2 x i32> %val) {
%mask = icmp eq <2 x i32> %trigger, zeroinitializer
- call void @llvm.masked.store.v2i32(<2 x i32>%val, <2 x i32>* %addr, i32 4, <2 x i1>%mask)
+ call void @llvm.masked.store.v2i32.p0v2i32(<2 x i32>%val, <2 x i32>* %addr, i32 4, <2 x i1>%mask)
ret void
}
@@ -55,7 +55,7 @@ define void @test6(<2 x i32> %trigger, <2 x i32>* %addr, <2 x i32> %val) {
; AVX2: Found an estimated cost of 5 {{.*}}.masked
define <2 x float> @test7(<2 x i32> %trigger, <2 x float>* %addr, <2 x float> %dst) {
%mask = icmp eq <2 x i32> %trigger, zeroinitializer
- %res = call <2 x float> @llvm.masked.load.v2f32(<2 x float>* %addr, i32 4, <2 x i1>%mask, <2 x float>%dst)
+ %res = call <2 x float> @llvm.masked.load.v2f32.p0v2f32(<2 x float>* %addr, i32 4, <2 x i1>%mask, <2 x float>%dst)
ret <2 x float> %res
}
@@ -63,7 +63,7 @@ define <2 x float> @test7(<2 x i32> %trigger, <2 x float>* %addr, <2 x float> %d
; AVX2: Found an estimated cost of 6 {{.*}}.masked
define <2 x i32> @test8(<2 x i32> %trigger, <2 x i32>* %addr, <2 x i32> %dst) {
%mask = icmp eq <2 x i32> %trigger, zeroinitializer
- %res = call <2 x i32> @llvm.masked.load.v2i32(<2 x i32>* %addr, i32 4, <2 x i1>%mask, <2 x i32>%dst)
+ %res = call <2 x i32> @llvm.masked.load.v2i32.p0v2i32(<2 x i32>* %addr, i32 4, <2 x i1>%mask, <2 x i32>%dst)
ret <2 x i32> %res
}
@@ -279,24 +279,22 @@ declare void @llvm.masked.scatter.v4i32(<4 x i32> %a1, <4 x i32*> %ptr, i32, <4
declare void @llvm.masked.scatter.v16i32(<16 x i32>%val, <16 x i32*> %gep.random, i32, <16 x i1> %imask)
declare <16 x float> @llvm.masked.gather.v16f32(<16 x float*> %gep.v, i32, <16 x i1> %mask, <16 x float>)
-declare <16 x i32> @llvm.masked.load.v16i32(<16 x i32>*, i32, <16 x i1>, <16 x i32>)
-declare <4 x i32> @llvm.masked.load.v4i32(<4 x i32>*, i32, <4 x i1>, <4 x i32>)
-declare <2 x i32> @llvm.masked.load.v2i32(<2 x i32>*, i32, <2 x i1>, <2 x i32>)
-declare void @llvm.masked.store.v16i32(<16 x i32>, <16 x i32>*, i32, <16 x i1>)
-declare void @llvm.masked.store.v8i32(<8 x i32>, <8 x i32>*, i32, <8 x i1>)
-declare void @llvm.masked.store.v4i32(<4 x i32>, <4 x i32>*, i32, <4 x i1>)
-declare void @llvm.masked.store.v2f32(<2 x float>, <2 x float>*, i32, <2 x i1>)
-declare void @llvm.masked.store.v2i32(<2 x i32>, <2 x i32>*, i32, <2 x i1>)
-declare void @llvm.masked.store.v16f32(<16 x float>, <16 x float>*, i32, <16 x i1>)
-declare void @llvm.masked.store.v16f32p(<16 x float>*, <16 x float>**, i32, <16 x i1>)
-declare <16 x float> @llvm.masked.load.v16f32(<16 x float>*, i32, <16 x i1>, <16 x float>)
-declare <8 x float> @llvm.masked.load.v8f32(<8 x float>*, i32, <8 x i1>, <8 x float>)
-declare <4 x float> @llvm.masked.load.v4f32(<4 x float>*, i32, <4 x i1>, <4 x float>)
-declare <2 x float> @llvm.masked.load.v2f32(<2 x float>*, i32, <2 x i1>, <2 x float>)
-declare <8 x double> @llvm.masked.load.v8f64(<8 x double>*, i32, <8 x i1>, <8 x double>)
-declare <4 x double> @llvm.masked.load.v4f64(<4 x double>*, i32, <4 x i1>, <4 x double>)
-declare <2 x double> @llvm.masked.load.v2f64(<2 x double>*, i32, <2 x i1>, <2 x double>)
-declare void @llvm.masked.store.v8f64(<8 x double>, <8 x double>*, i32, <8 x i1>)
-declare void @llvm.masked.store.v2f64(<2 x double>, <2 x double>*, i32, <2 x i1>)
-declare void @llvm.masked.store.v2i64(<2 x i64>, <2 x i64>*, i32, <2 x i1>)
-
+declare <16 x i32> @llvm.masked.load.v16i32.p0v16i32(<16 x i32>*, i32, <16 x i1>, <16 x i32>)
+declare <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>*, i32, <4 x i1>, <4 x i32>)
+declare <2 x i32> @llvm.masked.load.v2i32.p0v2i32(<2 x i32>*, i32, <2 x i1>, <2 x i32>)
+declare void @llvm.masked.store.v16i32.p0v16i32(<16 x i32>, <16 x i32>*, i32, <16 x i1>)
+declare void @llvm.masked.store.v8i32.p0v8i32(<8 x i32>, <8 x i32>*, i32, <8 x i1>)
+declare void @llvm.masked.store.v4i32.p0v4i32(<4 x i32>, <4 x i32>*, i32, <4 x i1>)
+declare void @llvm.masked.store.v2f32.p0v2f32(<2 x float>, <2 x float>*, i32, <2 x i1>)
+declare void @llvm.masked.store.v2i32.p0v2i32(<2 x i32>, <2 x i32>*, i32, <2 x i1>)
+declare void @llvm.masked.store.v16f32.p0v16f32(<16 x float>, <16 x float>*, i32, <16 x i1>)
+declare <16 x float> @llvm.masked.load.v16f32.p0v16f32(<16 x float>*, i32, <16 x i1>, <16 x float>)
+declare <8 x float> @llvm.masked.load.v8f32.p0v8f32(<8 x float>*, i32, <8 x i1>, <8 x float>)
+declare <4 x float> @llvm.masked.load.v4f32.p0v4f32(<4 x float>*, i32, <4 x i1>, <4 x float>)
+declare <2 x float> @llvm.masked.load.v2f32.p0v2f32(<2 x float>*, i32, <2 x i1>, <2 x float>)
+declare <8 x double> @llvm.masked.load.v8f64.p0v8f64(<8 x double>*, i32, <8 x i1>, <8 x double>)
+declare <4 x double> @llvm.masked.load.v4f64.p0v4f64(<4 x double>*, i32, <4 x i1>, <4 x double>)
+declare <2 x double> @llvm.masked.load.v2f64.p0v2f64(<2 x double>*, i32, <2 x i1>, <2 x double>)
+declare void @llvm.masked.store.v8f64.p0v8f64(<8 x double>, <8 x double>*, i32, <8 x i1>)
+declare void @llvm.masked.store.v2f64.p0v2f64(<2 x double>, <2 x double>*, i32, <2 x i1>)
+declare void @llvm.masked.store.v2i64.p0v2i64(<2 x i64>, <2 x i64>*, i32, <2 x i1>)
diff --git a/test/Analysis/CostModel/X86/scalarize.ll b/test/Analysis/CostModel/X86/scalarize.ll
index fc25fcbc563f6..fd4e3005bd9f8 100644
--- a/test/Analysis/CostModel/X86/scalarize.ll
+++ b/test/Analysis/CostModel/X86/scalarize.ll
@@ -13,27 +13,27 @@
declare %i4 @llvm.bswap.v4i32(%i4)
declare %i8 @llvm.bswap.v2i64(%i8)
-declare %i4 @llvm.ctpop.v4i32(%i4)
-declare %i8 @llvm.ctpop.v2i64(%i8)
+declare %i4 @llvm.cttz.v4i32(%i4)
+declare %i8 @llvm.cttz.v2i64(%i8)
; CHECK32-LABEL: test_scalarized_intrinsics
; CHECK64-LABEL: test_scalarized_intrinsics
define void @test_scalarized_intrinsics() {
%r1 = add %i8 undef, undef
-; CHECK32: cost of 12 {{.*}}bswap.v4i32
-; CHECK64: cost of 12 {{.*}}bswap.v4i32
+; CHECK32: cost of 1 {{.*}}bswap.v4i32
+; CHECK64: cost of 1 {{.*}}bswap.v4i32
%r2 = call %i4 @llvm.bswap.v4i32(%i4 undef)
-; CHECK32: cost of 10 {{.*}}bswap.v2i64
-; CHECK64: cost of 6 {{.*}}bswap.v2i64
+; CHECK32: cost of 1 {{.*}}bswap.v2i64
+; CHECK64: cost of 1 {{.*}}bswap.v2i64
%r3 = call %i8 @llvm.bswap.v2i64(%i8 undef)
-; CHECK32: cost of 12 {{.*}}ctpop.v4i32
-; CHECK64: cost of 12 {{.*}}ctpop.v4i32
- %r4 = call %i4 @llvm.ctpop.v4i32(%i4 undef)
-; CHECK32: cost of 10 {{.*}}ctpop.v2i64
-; CHECK64: cost of 6 {{.*}}ctpop.v2i64
- %r5 = call %i8 @llvm.ctpop.v2i64(%i8 undef)
+; CHECK32: cost of 12 {{.*}}cttz.v4i32
+; CHECK64: cost of 12 {{.*}}cttz.v4i32
+ %r4 = call %i4 @llvm.cttz.v4i32(%i4 undef)
+; CHECK32: cost of 10 {{.*}}cttz.v2i64
+; CHECK64: cost of 6 {{.*}}cttz.v2i64
+ %r5 = call %i8 @llvm.cttz.v2i64(%i8 undef)
; CHECK32: ret
; CHECK64: ret
diff --git a/test/Analysis/CostModel/X86/sitofp.ll b/test/Analysis/CostModel/X86/sitofp.ll
index 9f0c4065c1788..fb390a2b17aa9 100644
--- a/test/Analysis/CostModel/X86/sitofp.ll
+++ b/test/Analysis/CostModel/X86/sitofp.ll
@@ -40,10 +40,10 @@ define <8 x double> @sitofpv8i8v8double(<8 x i8> %a) {
; SSE2: cost of 80 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv8i8v8double
- ; AVX1: cost of 20 {{.*}} sitofp
+ ; AVX1: cost of 7 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv8i8v8double
- ; AVX2: cost of 20 {{.*}} sitofp
+ ; AVX2: cost of 7 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv8i8v8double
; AVX512F: cost of 2 {{.*}} sitofp
@@ -56,13 +56,13 @@ define <16 x double> @sitofpv16i8v16double(<16 x i8> %a) {
; SSE2: cost of 160 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv16i8v16double
- ; AVX1: cost of 40 {{.*}} sitofp
+ ; AVX1: cost of 15 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv16i8v16double
- ; AVX2: cost of 40 {{.*}} sitofp
+ ; AVX2: cost of 15 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv16i8v16double
- ; AVX512F: cost of 44 {{.*}} sitofp
+ ; AVX512F: cost of 5 {{.*}} sitofp
%1 = sitofp <16 x i8> %a to <16 x double>
ret <16 x double> %1
}
@@ -72,13 +72,13 @@ define <32 x double> @sitofpv32i8v32double(<32 x i8> %a) {
; SSE2: cost of 320 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv32i8v32double
- ; AVX1: cost of 80 {{.*}} sitofp
+ ; AVX1: cost of 31 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv32i8v32double
- ; AVX2: cost of 80 {{.*}} sitofp
+ ; AVX2: cost of 31 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv32i8v32double
- ; AVX512F: cost of 88 {{.*}} sitofp
+ ; AVX512F: cost of 11 {{.*}} sitofp
%1 = sitofp <32 x i8> %a to <32 x double>
ret <32 x double> %1
}
@@ -120,10 +120,10 @@ define <8 x double> @sitofpv8i16v8double(<8 x i16> %a) {
; SSE2: cost of 80 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv8i16v8double
- ; AVX1: cost of 20 {{.*}} sitofp
+ ; AVX1: cost of 7 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv8i16v8double
- ; AVX2: cost of 20 {{.*}} sitofp
+ ; AVX2: cost of 7 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv8i16v8double
; AVX512F: cost of 2 {{.*}} sitofp
@@ -136,13 +136,13 @@ define <16 x double> @sitofpv16i16v16double(<16 x i16> %a) {
; SSE2: cost of 160 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv16i16v16double
- ; AVX1: cost of 40 {{.*}} sitofp
+ ; AVX1: cost of 15 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv16i16v16double
- ; AVX2: cost of 40 {{.*}} sitofp
+ ; AVX2: cost of 15 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv16i16v16double
- ; AVX512F: cost of 44 {{.*}} sitofp
+ ; AVX512F: cost of 5 {{.*}} sitofp
%1 = sitofp <16 x i16> %a to <16 x double>
ret <16 x double> %1
}
@@ -152,13 +152,13 @@ define <32 x double> @sitofpv32i16v32double(<32 x i16> %a) {
; SSE2: cost of 320 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv32i16v32double
- ; AVX1: cost of 80 {{.*}} sitofp
+ ; AVX1: cost of 31 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv32i16v32double
- ; AVX2: cost of 80 {{.*}} sitofp
+ ; AVX2: cost of 31 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv32i16v32double
- ; AVX512F: cost of 88 {{.*}} sitofp
+ ; AVX512F: cost of 11 {{.*}} sitofp
%1 = sitofp <32 x i16> %a to <32 x double>
ret <32 x double> %1
}
@@ -200,10 +200,10 @@ define <8 x double> @sitofpv8i32v8double(<8 x i32> %a) {
; SSE2: cost of 80 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv8i32v8double
- ; AVX1: cost of 20 {{.*}} sitofp
+ ; AVX1: cost of 3 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv8i32v8double
- ; AVX2: cost of 20 {{.*}} sitofp
+ ; AVX2: cost of 3 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv8i32v8double
; AVX512F: cost of 1 {{.*}} sitofp
@@ -216,13 +216,13 @@ define <16 x double> @sitofpv16i32v16double(<16 x i32> %a) {
; SSE2: cost of 160 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv16i32v16double
- ; AVX1: cost of 40 {{.*}} sitofp
+ ; AVX1: cost of 7 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv16i32v16double
- ; AVX2: cost of 40 {{.*}} sitofp
+ ; AVX2: cost of 7 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv16i32v16double
- ; AVX512F: cost of 44 {{.*}} sitofp
+ ; AVX512F: cost of 3 {{.*}} sitofp
%1 = sitofp <16 x i32> %a to <16 x double>
ret <16 x double> %1
}
@@ -232,13 +232,13 @@ define <32 x double> @sitofpv32i32v32double(<32 x i32> %a) {
; SSE2: cost of 320 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv32i32v32double
- ; AVX1: cost of 80 {{.*}} sitofp
+ ; AVX1: cost of 15 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv32i32v32double
- ; AVX2: cost of 80 {{.*}} sitofp
+ ; AVX2: cost of 15 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv32i32v32double
- ; AVX512F: cost of 88 {{.*}} sitofp
+ ; AVX512F: cost of 7 {{.*}} sitofp
%1 = sitofp <32 x i32> %a to <32 x double>
ret <32 x double> %1
}
@@ -264,13 +264,13 @@ define <4 x double> @sitofpv4i64v4double(<4 x i64> %a) {
; SSE2: cost of 40 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv4i64v4double
- ; AVX1: cost of 10 {{.*}} sitofp
+ ; AVX1: cost of 13 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv4i64v4double
- ; AVX2: cost of 10 {{.*}} sitofp
+ ; AVX2: cost of 13 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv4i64v4double
- ; AVX512F: cost of 10 {{.*}} sitofp
+ ; AVX512F: cost of 13 {{.*}} sitofp
%1 = sitofp <4 x i64> %a to <4 x double>
ret <4 x double> %1
}
@@ -280,10 +280,10 @@ define <8 x double> @sitofpv8i64v8double(<8 x i64> %a) {
; SSE2: cost of 80 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv8i64v8double
- ; AVX1: cost of 20 {{.*}} sitofp
+ ; AVX1: cost of 27 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv8i64v8double
- ; AVX2: cost of 20 {{.*}} sitofp
+ ; AVX2: cost of 27 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv8i64v8double
; AVX512F: cost of 22 {{.*}} sitofp
@@ -296,13 +296,13 @@ define <16 x double> @sitofpv16i64v16double(<16 x i64> %a) {
; SSE2: cost of 160 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv16i64v16double
- ; AVX1: cost of 40 {{.*}} sitofp
+ ; AVX1: cost of 55 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv16i64v16double
- ; AVX2: cost of 40 {{.*}} sitofp
+ ; AVX2: cost of 55 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv16i64v16double
- ; AVX512F: cost of 44 {{.*}} sitofp
+ ; AVX512F: cost of 45 {{.*}} sitofp
%1 = sitofp <16 x i64> %a to <16 x double>
ret <16 x double> %1
}
@@ -312,13 +312,13 @@ define <32 x double> @sitofpv32i64v32double(<32 x i64> %a) {
; SSE2: cost of 320 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv32i64v32double
- ; AVX1: cost of 80 {{.*}} sitofp
+ ; AVX1: cost of 111 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv32i64v32double
- ; AVX2: cost of 80 {{.*}} sitofp
+ ; AVX2: cost of 111 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv32i64v32double
- ; AVX512F: cost of 88 {{.*}} sitofp
+ ; AVX512F: cost of 91 {{.*}} sitofp
%1 = sitofp <32 x i64> %a to <32 x double>
ret <32 x double> %1
}
@@ -341,7 +341,7 @@ define <2 x float> @sitofpv2i8v2float(<2 x i8> %a) {
define <4 x float> @sitofpv4i8v4float(<4 x i8> %a) {
; SSE2-LABEL: sitofpv4i8v4float
- ; SSE2: cost of 15 {{.*}} sitofp
+ ; SSE2: cost of 5 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv4i8v4float
; AVX1: cost of 3 {{.*}} sitofp
@@ -376,10 +376,10 @@ define <16 x float> @sitofpv16i8v16float(<16 x i8> %a) {
; SSE2: cost of 8 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv16i8v16float
- ; AVX1: cost of 44 {{.*}} sitofp
+ ; AVX1: cost of 17 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv16i8v16float
- ; AVX2: cost of 44 {{.*}} sitofp
+ ; AVX2: cost of 17 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv16i8v16float
; AVX512F: cost of 2 {{.*}} sitofp
@@ -392,13 +392,13 @@ define <32 x float> @sitofpv32i8v32float(<32 x i8> %a) {
; SSE2: cost of 16 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv32i8v32float
- ; AVX1: cost of 88 {{.*}} sitofp
+ ; AVX1: cost of 35 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv32i8v32float
- ; AVX2: cost of 88 {{.*}} sitofp
+ ; AVX2: cost of 35 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv32i8v32float
- ; AVX512F: cost of 92 {{.*}} sitofp
+ ; AVX512F: cost of 5 {{.*}} sitofp
%1 = sitofp <32 x i8> %a to <32 x float>
ret <32 x float> %1
}
@@ -421,7 +421,7 @@ define <2 x float> @sitofpv2i16v2float(<2 x i16> %a) {
define <4 x float> @sitofpv4i16v4float(<4 x i16> %a) {
; SSE2-LABEL: sitofpv4i16v4float
- ; SSE2: cost of 15 {{.*}} sitofp
+ ; SSE2: cost of 5 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv4i16v4float
; AVX1: cost of 3 {{.*}} sitofp
@@ -456,10 +456,10 @@ define <16 x float> @sitofpv16i16v16float(<16 x i16> %a) {
; SSE2: cost of 30 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv16i16v16float
- ; AVX1: cost of 44 {{.*}} sitofp
+ ; AVX1: cost of 11 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv16i16v16float
- ; AVX2: cost of 44 {{.*}} sitofp
+ ; AVX2: cost of 11 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv16i16v16float
; AVX512F: cost of 2 {{.*}} sitofp
@@ -472,13 +472,13 @@ define <32 x float> @sitofpv32i16v32float(<32 x i16> %a) {
; SSE2: cost of 60 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv32i16v32float
- ; AVX1: cost of 88 {{.*}} sitofp
+ ; AVX1: cost of 23 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv32i16v32float
- ; AVX2: cost of 88 {{.*}} sitofp
+ ; AVX2: cost of 23 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv32i16v32float
- ; AVX512F: cost of 92 {{.*}} sitofp
+ ; AVX512F: cost of 5 {{.*}} sitofp
%1 = sitofp <32 x i16> %a to <32 x float>
ret <32 x float> %1
}
@@ -501,7 +501,7 @@ define <2 x float> @sitofpv2i32v2float(<2 x i32> %a) {
define <4 x float> @sitofpv4i32v4float(<4 x i32> %a) {
; SSE2-LABEL: sitofpv4i32v4float
- ; SSE2: cost of 15 {{.*}} sitofp
+ ; SSE2: cost of 5 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv4i32v4float
; AVX1: cost of 1 {{.*}} sitofp
@@ -517,7 +517,7 @@ define <4 x float> @sitofpv4i32v4float(<4 x i32> %a) {
define <8 x float> @sitofpv8i32v8float(<8 x i32> %a) {
; SSE2-LABEL: sitofpv8i32v8float
- ; SSE2: cost of 30 {{.*}} sitofp
+ ; SSE2: cost of 10 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv8i32v8float
; AVX1: cost of 1 {{.*}} sitofp
@@ -533,13 +533,13 @@ define <8 x float> @sitofpv8i32v8float(<8 x i32> %a) {
define <16 x float> @sitofpv16i32v16float(<16 x i32> %a) {
; SSE2-LABEL: sitofpv16i32v16float
- ; SSE2: cost of 60 {{.*}} sitofp
+ ; SSE2: cost of 20 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv16i32v16float
- ; AVX1: cost of 44 {{.*}} sitofp
+ ; AVX1: cost of 3 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv16i32v16float
- ; AVX2: cost of 44 {{.*}} sitofp
+ ; AVX2: cost of 3 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv16i32v16float
; AVX512F: cost of 1 {{.*}} sitofp
@@ -549,16 +549,16 @@ define <16 x float> @sitofpv16i32v16float(<16 x i32> %a) {
define <32 x float> @sitofpv32i32v32float(<32 x i32> %a) {
; SSE2-LABEL: sitofpv32i32v32float
- ; SSE2: cost of 120 {{.*}} sitofp
+ ; SSE2: cost of 40 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv32i32v32float
- ; AVX1: cost of 88 {{.*}} sitofp
+ ; AVX1: cost of 7 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv32i32v32float
- ; AVX2: cost of 88 {{.*}} sitofp
+ ; AVX2: cost of 7 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv32i32v32float
- ; AVX512F: cost of 92 {{.*}} sitofp
+ ; AVX512F: cost of 3 {{.*}} sitofp
%1 = sitofp <32 x i32> %a to <32 x float>
ret <32 x float> %1
}
@@ -600,10 +600,10 @@ define <8 x float> @sitofpv8i64v8float(<8 x i64> %a) {
; SSE2: cost of 60 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv8i64v8float
- ; AVX1: cost of 22 {{.*}} sitofp
+ ; AVX1: cost of 21 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv8i64v8float
- ; AVX2: cost of 22 {{.*}} sitofp
+ ; AVX2: cost of 21 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv8i64v8float
; AVX512F: cost of 22 {{.*}} sitofp
@@ -616,13 +616,13 @@ define <16 x float> @sitofpv16i64v16float(<16 x i64> %a) {
; SSE2: cost of 120 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv16i64v16float
- ; AVX1: cost of 44 {{.*}} sitofp
+ ; AVX1: cost of 43 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv16i64v16float
- ; AVX2: cost of 44 {{.*}} sitofp
+ ; AVX2: cost of 43 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv16i64v16float
- ; AVX512F: cost of 46 {{.*}} sitofp
+ ; AVX512F: cost of 45 {{.*}} sitofp
%1 = sitofp <16 x i64> %a to <16 x float>
ret <16 x float> %1
}
@@ -632,13 +632,13 @@ define <32 x float> @sitofpv32i64v32float(<32 x i64> %a) {
; SSE2: cost of 240 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv32i64v32float
- ; AVX1: cost of 88 {{.*}} sitofp
+ ; AVX1: cost of 87 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv32i64v32float
- ; AVX2: cost of 88 {{.*}} sitofp
+ ; AVX2: cost of 87 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv32i64v32float
- ; AVX512F: cost of 92 {{.*}} sitofp
+ ; AVX512F: cost of 91 {{.*}} sitofp
%1 = sitofp <32 x i64> %a to <32 x float>
ret <32 x float> %1
}
@@ -648,10 +648,10 @@ define <8 x double> @sitofpv8i1v8double(<8 x double> %a) {
; SSE2: cost of 80 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv8i1v8double
- ; AVX1: cost of 20 {{.*}} sitofp
+ ; AVX1: cost of 7 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv8i1v8double
- ; AVX2: cost of 20 {{.*}} sitofp
+ ; AVX2: cost of 7 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv8i1v8double
; AVX512F: cost of 4 {{.*}} sitofp
@@ -665,10 +665,10 @@ define <16 x float> @sitofpv16i1v16float(<16 x float> %a) {
; SSE2: cost of 8 {{.*}} sitofp
;
; AVX1-LABEL: sitofpv16i1v16float
- ; AVX1: cost of 44 {{.*}} sitofp
+ ; AVX1: cost of 17 {{.*}} sitofp
;
; AVX2-LABEL: sitofpv16i1v16float
- ; AVX2: cost of 44 {{.*}} sitofp
+ ; AVX2: cost of 17 {{.*}} sitofp
;
; AVX512F-LABEL: sitofpv16i1v16float
; AVX512F: cost of 3 {{.*}} sitofp
diff --git a/test/Analysis/CostModel/X86/sse-itoi.ll b/test/Analysis/CostModel/X86/sse-itoi.ll
index 9e7f26e54d29a..46d9935646098 100644
--- a/test/Analysis/CostModel/X86/sse-itoi.ll
+++ b/test/Analysis/CostModel/X86/sse-itoi.ll
@@ -1,6 +1,85 @@
; RUN: opt -mtriple=x86_64-apple-darwin -mattr=+sse2 -cost-model -analyze < %s | FileCheck --check-prefix=SSE2 %s
; RUN: opt -mtriple=x86_64-apple-darwin -mattr=+sse4.1 -cost-model -analyze < %s | FileCheck --check-prefix=SSE41 %s
+define void @zext_v4i8_to_v4i64(<4 x i8>* %a) {
+; SSE2: zext_v4i8_to_v4i64
+; SSE2: cost of 4 {{.*}} zext
+;
+; SSE41: zext_v4i8_to_v4i64
+; SSE41: cost of 2 {{.*}} zext
+;
+ %1 = load <4 x i8>, <4 x i8>* %a
+ %2 = zext <4 x i8> %1 to <4 x i64>
+ store <4 x i64> %2, <4 x i64>* undef, align 4
+ ret void
+}
+
+define void @sext_v4i8_to_v4i64(<4 x i8>* %a) {
+; SSE2: sext_v4i8_to_v4i64
+; SSE2: cost of 8 {{.*}} sext
+;
+; SSE41: sext_v4i8_to_v4i64
+; SSE41: cost of 2 {{.*}} sext
+;
+ %1 = load <4 x i8>, <4 x i8>* %a
+ %2 = sext <4 x i8> %1 to <4 x i64>
+ store <4 x i64> %2, <4 x i64>* undef, align 4
+ ret void
+}
+
+define void @zext_v4i16_to_v4i64(<4 x i16>* %a) {
+; SSE2: zext_v4i16_to_v4i64
+; SSE2: cost of 3 {{.*}} zext
+;
+; SSE41: zext_v4i16_to_v4i64
+; SSE41: cost of 2 {{.*}} zext
+;
+ %1 = load <4 x i16>, <4 x i16>* %a
+ %2 = zext <4 x i16> %1 to <4 x i64>
+ store <4 x i64> %2, <4 x i64>* undef, align 4
+ ret void
+}
+
+define void @sext_v4i16_to_v4i64(<4 x i16>* %a) {
+; SSE2: sext_v4i16_to_v4i64
+; SSE2: cost of 10 {{.*}} sext
+;
+; SSE41: sext_v4i16_to_v4i64
+; SSE41: cost of 2 {{.*}} sext
+;
+ %1 = load <4 x i16>, <4 x i16>* %a
+ %2 = sext <4 x i16> %1 to <4 x i64>
+ store <4 x i64> %2, <4 x i64>* undef, align 4
+ ret void
+}
+
+
+define void @zext_v4i32_to_v4i64(<4 x i32>* %a) {
+; SSE2: zext_v4i32_to_v4i64
+; SSE2: cost of 3 {{.*}} zext
+;
+; SSE41: zext_v4i32_to_v4i64
+; SSE41: cost of 2 {{.*}} zext
+;
+ %1 = load <4 x i32>, <4 x i32>* %a
+ %2 = zext <4 x i32> %1 to <4 x i64>
+ store <4 x i64> %2, <4 x i64>* undef, align 4
+ ret void
+}
+
+define void @sext_v4i32_to_v4i64(<4 x i32>* %a) {
+; SSE2: sext_v4i32_to_v4i64
+; SSE2: cost of 5 {{.*}} sext
+;
+; SSE41: sext_v4i32_to_v4i64
+; SSE41: cost of 2 {{.*}} sext
+;
+ %1 = load <4 x i32>, <4 x i32>* %a
+ %2 = sext <4 x i32> %1 to <4 x i64>
+ store <4 x i64> %2, <4 x i64>* undef, align 4
+ ret void
+}
+
define void @zext_v16i16_to_v16i32(<16 x i16>* %a) {
; SSE2: zext_v16i16_to_v16i32
; SSE2: cost of 6 {{.*}} zext
@@ -279,7 +358,7 @@ define void @truncate_v16i32_to_v16i8(<16 x i32>* %a) {
; SSE2: cost of 7 {{.*}} trunc
;
; SSE41: truncate_v16i32_to_v16i8
-; SSE41: cost of 30 {{.*}} trunc
+; SSE41: cost of 7 {{.*}} trunc
;
%1 = load <16 x i32>, <16 x i32>* %a
%2 = trunc <16 x i32> %1 to <16 x i8>
diff --git a/test/Analysis/CostModel/X86/uitofp.ll b/test/Analysis/CostModel/X86/uitofp.ll
index 08e36650bec47..2eb8407974f79 100644
--- a/test/Analysis/CostModel/X86/uitofp.ll
+++ b/test/Analysis/CostModel/X86/uitofp.ll
@@ -41,10 +41,10 @@ define <8 x double> @uitofpv8i8v8double(<8 x i8> %a) {
; SSE2: cost of 80 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv8i8v8double
- ; AVX1: cost of 20 {{.*}} uitofp
+ ; AVX1: cost of 5 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv8i8v8double
- ; AVX2: cost of 20 {{.*}} uitofp
+ ; AVX2: cost of 5 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv8i8v8double
; AVX512F: cost of 2 {{.*}} uitofp
@@ -57,13 +57,13 @@ define <16 x double> @uitofpv16i8v16double(<16 x i8> %a) {
; SSE2: cost of 160 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv16i8v16double
- ; AVX1: cost of 40 {{.*}} uitofp
+ ; AVX1: cost of 11 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv16i8v16double
- ; AVX2: cost of 40 {{.*}} uitofp
+ ; AVX2: cost of 11 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv16i8v16double
- ; AVX512F: cost of 44 {{.*}} uitofp
+ ; AVX512F: cost of 5 {{.*}} uitofp
%1 = uitofp <16 x i8> %a to <16 x double>
ret <16 x double> %1
}
@@ -73,13 +73,13 @@ define <32 x double> @uitofpv32i8v32double(<32 x i8> %a) {
; SSE2: cost of 320 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv32i8v32double
- ; AVX1: cost of 80 {{.*}} uitofp
+ ; AVX1: cost of 23 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv32i8v32double
- ; AVX2: cost of 80 {{.*}} uitofp
+ ; AVX2: cost of 23 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv32i8v32double
- ; AVX512F: cost of 88 {{.*}} uitofp
+ ; AVX512F: cost of 11 {{.*}} uitofp
%1 = uitofp <32 x i8> %a to <32 x double>
ret <32 x double> %1
}
@@ -121,10 +121,10 @@ define <8 x double> @uitofpv8i16v8double(<8 x i16> %a) {
; SSE2: cost of 80 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv8i16v8double
- ; AVX1: cost of 20 {{.*}} uitofp
+ ; AVX1: cost of 5 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv8i16v8double
- ; AVX2: cost of 20 {{.*}} uitofp
+ ; AVX2: cost of 5 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv8i16v8double
; AVX512F: cost of 2 {{.*}} uitofp
@@ -137,13 +137,13 @@ define <16 x double> @uitofpv16i16v16double(<16 x i16> %a) {
; SSE2: cost of 160 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv16i16v16double
- ; AVX1: cost of 40 {{.*}} uitofp
+ ; AVX1: cost of 11 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv16i16v16double
- ; AVX2: cost of 40 {{.*}} uitofp
+ ; AVX2: cost of 11 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv16i16v16double
- ; AVX512F: cost of 44 {{.*}} uitofp
+ ; AVX512F: cost of 5 {{.*}} uitofp
%1 = uitofp <16 x i16> %a to <16 x double>
ret <16 x double> %1
}
@@ -153,13 +153,13 @@ define <32 x double> @uitofpv32i16v32double(<32 x i16> %a) {
; SSE2: cost of 320 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv32i16v32double
- ; AVX1: cost of 80 {{.*}} uitofp
+ ; AVX1: cost of 23 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv32i16v32double
- ; AVX2: cost of 80 {{.*}} uitofp
+ ; AVX2: cost of 23 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv32i16v32double
- ; AVX512F: cost of 88 {{.*}} uitofp
+ ; AVX512F: cost of 11 {{.*}} uitofp
%1 = uitofp <32 x i16> %a to <32 x double>
ret <32 x double> %1
}
@@ -169,13 +169,13 @@ define <2 x double> @uitofpv2i32v2double(<2 x i32> %a) {
; SSE2: cost of 20 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv2i32v2double
- ; AVX1: cost of 4 {{.*}} uitofp
+ ; AVX1: cost of 6 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv2i32v2double
- ; AVX2: cost of 4 {{.*}} uitofp
+ ; AVX2: cost of 6 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv2i32v2double
- ; AVX512F: cost of 4 {{.*}} uitofp
+ ; AVX512F: cost of 1 {{.*}} uitofp
%1 = uitofp <2 x i32> %a to <2 x double>
ret <2 x double> %1
}
@@ -201,10 +201,10 @@ define <8 x double> @uitofpv8i32v8double(<8 x i32> %a) {
; SSE2: cost of 80 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv8i32v8double
- ; AVX1: cost of 20 {{.*}} uitofp
+ ; AVX1: cost of 13 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv8i32v8double
- ; AVX2: cost of 20 {{.*}} uitofp
+ ; AVX2: cost of 13 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv8i32v8double
; AVX512F: cost of 1 {{.*}} uitofp
@@ -217,13 +217,13 @@ define <16 x double> @uitofpv16i32v16double(<16 x i32> %a) {
; SSE2: cost of 160 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv16i32v16double
- ; AVX1: cost of 40 {{.*}} uitofp
+ ; AVX1: cost of 27 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv16i32v16double
- ; AVX2: cost of 40 {{.*}} uitofp
+ ; AVX2: cost of 27 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv16i32v16double
- ; AVX512F: cost of 44 {{.*}} uitofp
+ ; AVX512F: cost of 3 {{.*}} uitofp
%1 = uitofp <16 x i32> %a to <16 x double>
ret <16 x double> %1
}
@@ -233,13 +233,13 @@ define <32 x double> @uitofpv32i32v32double(<32 x i32> %a) {
; SSE2: cost of 320 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv32i32v32double
- ; AVX1: cost of 80 {{.*}} uitofp
+ ; AVX1: cost of 55 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv32i32v32double
- ; AVX2: cost of 80 {{.*}} uitofp
+ ; AVX2: cost of 55 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv32i32v32double
- ; AVX512F: cost of 88 {{.*}} uitofp
+ ; AVX512F: cost of 7 {{.*}} uitofp
%1 = uitofp <32 x i32> %a to <32 x double>
ret <32 x double> %1
}
@@ -249,15 +249,15 @@ define <2 x double> @uitofpv2i64v2double(<2 x i64> %a) {
; SSE2: cost of 20 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv2i64v2double
- ; AVX1: cost of 20 {{.*}} uitofp
+ ; AVX1: cost of 10 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv2i64v2double
- ; AVX2: cost of 20 {{.*}} uitofp
+ ; AVX2: cost of 10 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv2i64v2double
; AVX512F: cost of 5 {{.*}} uitofp
;
- ; AVX512DQ: uitofpv2i64v2double
+ ; AVX512DQ-LABEL: uitofpv2i64v2double
; AVX512DQ: cost of 1 {{.*}} uitofp
%1 = uitofp <2 x i64> %a to <2 x double>
ret <2 x double> %1
@@ -268,15 +268,15 @@ define <4 x double> @uitofpv4i64v4double(<4 x i64> %a) {
; SSE2: cost of 40 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv4i64v4double
- ; AVX1: cost of 40 {{.*}} uitofp
+ ; AVX1: cost of 20 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv4i64v4double
- ; AVX2: cost of 40 {{.*}} uitofp
+ ; AVX2: cost of 20 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv4i64v4double
; AVX512F: cost of 12 {{.*}} uitofp
;
- ; AVX512DQ: uitofpv4i64v4double
+ ; AVX512DQ-LABEL: uitofpv4i64v4double
; AVX512DQ: cost of 1 {{.*}} uitofp
%1 = uitofp <4 x i64> %a to <4 x double>
ret <4 x double> %1
@@ -287,15 +287,15 @@ define <8 x double> @uitofpv8i64v8double(<8 x i64> %a) {
; SSE2: cost of 80 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv8i64v8double
- ; AVX1: cost of 20 {{.*}} uitofp
+ ; AVX1: cost of 41 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv8i64v8double
- ; AVX2: cost of 20 {{.*}} uitofp
+ ; AVX2: cost of 41 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv8i64v8double
; AVX512F: cost of 26 {{.*}} uitofp
;
- ; AVX512DQ: uitofpv8i64v8double
+ ; AVX512DQ-LABEL: uitofpv8i64v8double
; AVX512DQ: cost of 1 {{.*}} uitofp
%1 = uitofp <8 x i64> %a to <8 x double>
ret <8 x double> %1
@@ -306,16 +306,16 @@ define <16 x double> @uitofpv16i64v16double(<16 x i64> %a) {
; SSE2: cost of 160 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv16i64v16double
- ; AVX1: cost of 40 {{.*}} uitofp
+ ; AVX1: cost of 83 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv16i64v16double
- ; AVX2: cost of 40 {{.*}} uitofp
+ ; AVX2: cost of 83 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv16i64v16double
- ; AVX512F: cost of 44 {{.*}} uitofp
+ ; AVX512F: cost of 53 {{.*}} uitofp
;
- ; AVX512DQ: uitofpv16i64v16double
- ; AVX512DQ: cost of 44 {{.*}} uitofp
+ ; AVX512DQ-LABEL: uitofpv16i64v16double
+ ; AVX512DQ: cost of 3 {{.*}} uitofp
%1 = uitofp <16 x i64> %a to <16 x double>
ret <16 x double> %1
}
@@ -325,16 +325,16 @@ define <32 x double> @uitofpv32i64v32double(<32 x i64> %a) {
; SSE2: cost of 320 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv32i64v32double
- ; AVX1: cost of 80 {{.*}} uitofp
+ ; AVX1: cost of 167 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv32i64v32double
- ; AVX2: cost of 80 {{.*}} uitofp
+ ; AVX2: cost of 167 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv32i64v32double
- ; AVX512F: cost of 88 {{.*}} uitofp
+ ; AVX512F: cost of 107 {{.*}} uitofp
;
- ; AVX512DQ: uitofpv32i64v32double
- ; AVX512DQ: cost of 88 {{.*}} uitofp
+ ; AVX512DQ-LABEL: uitofpv32i64v32double
+ ; AVX512DQ: cost of 2 {{.*}} uitofp
%1 = uitofp <32 x i64> %a to <32 x double>
ret <32 x double> %1
}
@@ -392,10 +392,10 @@ define <16 x float> @uitofpv16i8v16float(<16 x i8> %a) {
; SSE2: cost of 8 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv16i8v16float
- ; AVX1: cost of 44 {{.*}} uitofp
+ ; AVX1: cost of 11 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv16i8v16float
- ; AVX2: cost of 44 {{.*}} uitofp
+ ; AVX2: cost of 11 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv16i8v16float
; AVX512F: cost of 2 {{.*}} uitofp
@@ -408,13 +408,13 @@ define <32 x float> @uitofpv32i8v32float(<32 x i8> %a) {
; SSE2: cost of 16 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv32i8v32float
- ; AVX1: cost of 88 {{.*}} uitofp
+ ; AVX1: cost of 23 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv32i8v32float
- ; AVX2: cost of 88 {{.*}} uitofp
+ ; AVX2: cost of 23 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv32i8v32float
- ; AVX512F: cost of 92 {{.*}} uitofp
+ ; AVX512F: cost of 5 {{.*}} uitofp
%1 = uitofp <32 x i8> %a to <32 x float>
ret <32 x float> %1
}
@@ -472,10 +472,10 @@ define <16 x float> @uitofpv16i16v16float(<16 x i16> %a) {
; SSE2: cost of 30 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv16i16v16float
- ; AVX1: cost of 44 {{.*}} uitofp
+ ; AVX1: cost of 11 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv16i16v16float
- ; AVX2: cost of 44 {{.*}} uitofp
+ ; AVX2: cost of 11 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv16i16v16float
; AVX512F: cost of 2 {{.*}} uitofp
@@ -488,13 +488,13 @@ define <32 x float> @uitofpv32i16v32float(<32 x i16> %a) {
; SSE2: cost of 60 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv32i16v32float
- ; AVX1: cost of 88 {{.*}} uitofp
+ ; AVX1: cost of 23 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv32i16v32float
- ; AVX2: cost of 88 {{.*}} uitofp
+ ; AVX2: cost of 23 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv32i16v32float
- ; AVX512F: cost of 92 {{.*}} uitofp
+ ; AVX512F: cost of 5 {{.*}} uitofp
%1 = uitofp <32 x i16> %a to <32 x float>
ret <32 x float> %1
}
@@ -552,10 +552,10 @@ define <16 x float> @uitofpv16i32v16float(<16 x i32> %a) {
; SSE2: cost of 32 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv16i32v16float
- ; AVX1: cost of 44 {{.*}} uitofp
+ ; AVX1: cost of 19 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv16i32v16float
- ; AVX2: cost of 44 {{.*}} uitofp
+ ; AVX2: cost of 17 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv16i32v16float
; AVX512F: cost of 1 {{.*}} uitofp
@@ -568,13 +568,13 @@ define <32 x float> @uitofpv32i32v32float(<32 x i32> %a) {
; SSE2: cost of 64 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv32i32v32float
- ; AVX1: cost of 88 {{.*}} uitofp
+ ; AVX1: cost of 39 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv32i32v32float
- ; AVX2: cost of 88 {{.*}} uitofp
+ ; AVX2: cost of 35 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv32i32v32float
- ; AVX512F: cost of 92 {{.*}} uitofp
+ ; AVX512F: cost of 3 {{.*}} uitofp
%1 = uitofp <32 x i32> %a to <32 x float>
ret <32 x float> %1
}
@@ -590,7 +590,7 @@ define <2 x float> @uitofpv2i64v2float(<2 x i64> %a) {
; AVX2: cost of 4 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv2i64v2float
- ; AVX512F: cost of 4 {{.*}} uitofp
+ ; AVX512F: cost of 5 {{.*}} uitofp
%1 = uitofp <2 x i64> %a to <2 x float>
ret <2 x float> %1
}
@@ -616,13 +616,13 @@ define <8 x float> @uitofpv8i64v8float(<8 x i64> %a) {
; SSE2: cost of 60 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv8i64v8float
- ; AVX1: cost of 22 {{.*}} uitofp
+ ; AVX1: cost of 21 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv8i64v8float
- ; AVX2: cost of 22 {{.*}} uitofp
+ ; AVX2: cost of 21 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv8i64v8float
- ; AVX512F: cost of 22 {{.*}} uitofp
+ ; AVX512F: cost of 26 {{.*}} uitofp
%1 = uitofp <8 x i64> %a to <8 x float>
ret <8 x float> %1
}
@@ -632,13 +632,13 @@ define <16 x float> @uitofpv16i64v16float(<16 x i64> %a) {
; SSE2: cost of 120 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv16i64v16float
- ; AVX1: cost of 44 {{.*}} uitofp
+ ; AVX1: cost of 43 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv16i64v16float
- ; AVX2: cost of 44 {{.*}} uitofp
+ ; AVX2: cost of 43 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv16i64v16float
- ; AVX512F: cost of 46 {{.*}} uitofp
+ ; AVX512F: cost of 53 {{.*}} uitofp
%1 = uitofp <16 x i64> %a to <16 x float>
ret <16 x float> %1
}
@@ -648,13 +648,13 @@ define <32 x float> @uitofpv32i64v32float(<32 x i64> %a) {
; SSE2: cost of 240 {{.*}} uitofp
;
; AVX1-LABEL: uitofpv32i64v32float
- ; AVX1: cost of 88 {{.*}} uitofp
+ ; AVX1: cost of 87 {{.*}} uitofp
;
; AVX2-LABEL: uitofpv32i64v32float
- ; AVX2: cost of 88 {{.*}} uitofp
+ ; AVX2: cost of 87 {{.*}} uitofp
;
; AVX512F-LABEL: uitofpv32i64v32float
- ; AVX512F: cost of 92 {{.*}} uitofp
+ ; AVX512F: cost of 107 {{.*}} uitofp
%1 = uitofp <32 x i64> %a to <32 x float>
ret <32 x float> %1
}
diff --git a/test/Analysis/DemandedBits/basic.ll b/test/Analysis/DemandedBits/basic.ll
index 3fd1b3212883d..5b8652396b3a1 100644
--- a/test/Analysis/DemandedBits/basic.ll
+++ b/test/Analysis/DemandedBits/basic.ll
@@ -1,6 +1,6 @@
; RUN: opt -S -demanded-bits -analyze < %s | FileCheck %s
-
-; CHECK-LABEL: 'test_mul'
+; RUN: opt -S -disable-output -passes="print<demanded-bits>" < %s 2>&1 | FileCheck %s
+
; CHECK-DAG: DemandedBits: 0xFF for %1 = add nsw i32 %a, 5
; CHECK-DAG: DemandedBits: 0xFF for %3 = trunc i32 %2 to i8
; CHECK-DAG: DemandedBits: 0xFF for %2 = mul nsw i32 %1, %b
diff --git a/test/Analysis/DependenceAnalysis/MIVCheckConst.ll b/test/Analysis/DependenceAnalysis/MIVCheckConst.ll
new file mode 100644
index 0000000000000..64e72df55b857
--- /dev/null
+++ b/test/Analysis/DependenceAnalysis/MIVCheckConst.ll
@@ -0,0 +1,73 @@
+; RUN: opt < %s -analyze -basicaa -da
+
+; Test that the dependence analysis pass does seg-fault due to a null pointer
+; dereference. The code in gcdMIVTest requires a null check for the result of
+; getConstantPart.
+
+target datalayout = "e-m:e-p:32:32-i1:32-i64:64-a:0-v32:32-n16:32"
+
+%0 = type { i32 }
+%1 = type { [2 x [512 x %0]], [512 x %0], %2, [144 x i8], %9, %10, %11, %12, %17, [12 x i8], %18, %19, %21, [128 x i8] }
+%2 = type { [64 x i16], [64 x i16], [64 x %0], [64 x %0], [128 x %0], [128 x %0], [256 x %0], [256 x %0], [32 x %0], [32 x %0], [64 x i16], [64 x i16], [64 x i16], [64 x i16], [64 x i16], %3, %4, %5, [32 x i32], [32 x i32], [32 x i32], [32 x i32], [32 x i32], [32 x i32], %6, %7, [32 x i32], [32 x i32], [32 x i32], [64 x i16], %8, [8 x i64], [4 x i64], [2 x i64], [256 x i8], [256 x i32], [64 x i16], [64 x i16] }
+%3 = type { [64 x i32], [32 x i32], [32 x i32], [32 x i32], [32 x i32], [32 x i32], [32 x i32], [32 x i32], [32 x i32], [32 x i32], [32 x i32], [32 x i32], [32 x i32], [32 x i32], [32 x i32], [64 x i32], [64 x i32], [64 x i32], [64 x i32], [64 x i32], [64 x i32], [64 x i32], [64 x i32], [64 x i32], [64 x i16], [64 x i16], [64 x i16], [64 x i16], [64 x i16], [64 x i16], [64 x i16], [64 x i16], [64 x i16], [64 x i16], [64 x i16], [64 x i16], [32 x %0], [32 x %0], [128 x i8] }
+%4 = type { [64 x i16], [64 x i16], [64 x i16], [64 x i16], [64 x i16], [64 x i16], [64 x i16], [64 x i16] }
+%5 = type { [128 x i8], [256 x i8], [256 x i8] }
+%6 = type { [64 x i32], [128 x i16], [64 x i16], [64 x i16], [64 x i16] }
+%7 = type { [192 x %0], [192 x %0], [384 x %0], [1984 x %0] }
+%8 = type { [128 x i8], [128 x i8], [64 x i16], [64 x i16], [64 x i16], [64 x i16], [64 x i16], [64 x i16] }
+%9 = type { [32 x %0], [32 x %0], [64 x i32], [64 x i32], [64 x i32], [64 x i32] }
+%10 = type { [1536 x %0], [2048 x %0], [512 x i32], [256 x i32], [32 x %0], [64 x i32], [128 x i8], [512 x i32], [1024 x %0] }
+%11 = type { [512 x i32], [512 x i32], [1024 x %0], [512 x i32], [512 x %0] }
+%12 = type { %13, [2048 x %0], [2048 x %0], [256 x i32], [1024 x i32], %14, [512 x %0], [256 x i32], %15, [4 x [256 x %0]], [4 x [256 x %0]], [256 x i32], [8 x [32 x i32]], [8 x [32 x %0]], [384 x %0], [256 x i32], %16 }
+%13 = type { [2048 x %0] }
+%14 = type { [1024 x %0], [1024 x %0] }
+%15 = type { [256 x %0], [256 x %0] }
+%16 = type { [128 x %0], [128 x %0] }
+%17 = type { [32 x %0], [32 x i32], [32 x i32], [32 x i32], [32 x i32], [2 x [8 x [32 x %0]]], [512 x %0], [512 x %0], [58 x i16] }
+%18 = type { [512 x i8] }
+%19 = type { [2048 x %0], [2560 x i16], %20, [512 x i32], [256 x i32], [512 x i8] }
+%20 = type { [768 x i32] }
+%21 = type { [416 x i32] }
+
+define void @test(%1* %A) #0 align 2 {
+entry:
+ %v1 = load i32, i32* undef, align 4
+ br label %bb13
+
+bb13:
+ %v2 = phi i32 [ undef, %entry ], [ %v39, %bb38 ]
+ br i1 undef, label %bb15, label %bb38
+
+bb15:
+ %v3 = mul nsw i32 %v2, undef
+ br label %bb17
+
+bb17:
+ br i1 undef, label %bb21, label %bb37
+
+bb21:
+ %v22 = add nsw i32 undef, 1
+ %v23 = add i32 %v22, %v3
+ %v24 = mul nsw i32 %v23, %v1
+ %v25 = getelementptr inbounds %1, %1* %A, i32 0, i32 7, i32 1, i32 %v24
+ %v26 = bitcast %0* %v25 to <32 x i32>*
+ %v27 = load <32 x i32>, <32 x i32>* %v26, align 256
+ %v28 = add i32 undef, %v3
+ %v29 = mul nsw i32 %v28, 32
+ %v30 = getelementptr inbounds %1, %1* %A, i32 0, i32 7, i32 14, i32 %v29
+ %v31 = bitcast %0* %v30 to <32 x i32>*
+ %v32 = load <32 x i32>, <32 x i32>* %v31, align 128
+ br i1 undef, label %bb21, label %bb37
+
+bb37:
+ br i1 undef, label %bb17, label %bb38
+
+bb38:
+ %v39 = add nsw i32 %v2, 1
+ br label %bb13
+
+bb40:
+ ret void
+}
+
+attributes #0 = { "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/Analysis/DivergenceAnalysis/AMDGPU/atomics.ll b/test/Analysis/DivergenceAnalysis/AMDGPU/atomics.ll
new file mode 100644
index 0000000000000..e3323dc5e21c2
--- /dev/null
+++ b/test/Analysis/DivergenceAnalysis/AMDGPU/atomics.ll
@@ -0,0 +1,15 @@
+; RUN: opt -mtriple=amdgcn-- -analyze -divergence %s | FileCheck %s
+
+; CHECK: DIVERGENT: %orig = atomicrmw xchg i32* %ptr, i32 %val seq_cst
+define i32 @test1(i32* %ptr, i32 %val) #0 {
+ %orig = atomicrmw xchg i32* %ptr, i32 %val seq_cst
+ ret i32 %orig
+}
+
+; CHECK: DIVERGENT: %orig = cmpxchg i32* %ptr, i32 %cmp, i32 %new seq_cst seq_cst
+define {i32, i1} @test2(i32* %ptr, i32 %cmp, i32 %new) {
+ %orig = cmpxchg i32* %ptr, i32 %cmp, i32 %new seq_cst seq_cst
+ ret {i32, i1} %orig
+}
+
+attributes #0 = { nounwind }
diff --git a/test/Analysis/DivergenceAnalysis/AMDGPU/interp-intrinsics.ll b/test/Analysis/DivergenceAnalysis/AMDGPU/interp-intrinsics.ll
new file mode 100644
index 0000000000000..d1c90ba608c8d
--- /dev/null
+++ b/test/Analysis/DivergenceAnalysis/AMDGPU/interp-intrinsics.ll
@@ -0,0 +1,22 @@
+; RUN: opt -mtriple amdgcn--- -analyze -divergence %s | FileCheck %s
+
+; CHECK-LABEL: 'fs_interp'
+; CHECK: DIVERGENT: %v = call float @llvm.SI.fs.interp(
+define amdgpu_ps void @fs_interp(i32 inreg %prim_mask, <2 x i32> %interp_param) #1 {
+ %v = call float @llvm.SI.fs.interp(i32 0, i32 0, i32 %prim_mask, <2 x i32> %interp_param)
+ store volatile float %v, float addrspace(1)* undef
+ ret void
+}
+
+; CHECK-LABEL: 'fs_constant'
+; CHECK: DIVERGENT: %v = call float @llvm.SI.fs.constant(
+define amdgpu_ps void @fs_constant(i32 inreg %prim_mask, <2 x i32> %interp_param) #1 {
+ %v = call float @llvm.SI.fs.constant(i32 0, i32 0, i32 %prim_mask)
+ store volatile float %v, float addrspace(1)* undef
+ ret void
+}
+
+declare float @llvm.SI.fs.interp(i32, i32, i32, <2 x i32>) #0
+declare float @llvm.SI.fs.constant(i32, i32, i32) #0
+
+attributes #0 = { nounwind readnone }
diff --git a/test/Analysis/DivergenceAnalysis/AMDGPU/kernel-args.ll b/test/Analysis/DivergenceAnalysis/AMDGPU/kernel-args.ll
index 63e6c5c50ded9..73674d0599e25 100644
--- a/test/Analysis/DivergenceAnalysis/AMDGPU/kernel-args.ll
+++ b/test/Analysis/DivergenceAnalysis/AMDGPU/kernel-args.ll
@@ -9,8 +9,8 @@
; CHECK: DIVERGENT: float %arg5
; CHECK: DIVERGENT: i32 %arg6
-define void @main([4 x <16 x i8>] addrspace(2)* byval %arg0, float inreg %arg1, i32 inreg %arg2, <2 x i32> %arg3, <3 x i32> %arg4, float %arg5, i32 %arg6) #0 {
+define amdgpu_ps void @main([4 x <16 x i8>] addrspace(2)* byval %arg0, float inreg %arg1, i32 inreg %arg2, <2 x i32> %arg3, <3 x i32> %arg4, float %arg5, i32 %arg6) #0 {
ret void
}
-attributes #0 = { "ShaderType"="0" }
+attributes #0 = { nounwind }
diff --git a/test/Analysis/DivergenceAnalysis/AMDGPU/llvm.amdgcn.buffer.atomic.ll b/test/Analysis/DivergenceAnalysis/AMDGPU/llvm.amdgcn.buffer.atomic.ll
new file mode 100644
index 0000000000000..1d016453301f7
--- /dev/null
+++ b/test/Analysis/DivergenceAnalysis/AMDGPU/llvm.amdgcn.buffer.atomic.ll
@@ -0,0 +1,103 @@
+;RUN: opt -mtriple=amdgcn-mesa-mesa3d -analyze -divergence %s | FileCheck %s
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.buffer.atomic.swap(
+define float @buffer_atomic_swap(<4 x i32> inreg %rsrc, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.buffer.atomic.swap(i32 %data, <4 x i32> %rsrc, i32 0, i32 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.buffer.atomic.add(
+define float @buffer_atomic_add(<4 x i32> inreg %rsrc, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.buffer.atomic.add(i32 %data, <4 x i32> %rsrc, i32 0, i32 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.buffer.atomic.sub(
+define float @buffer_atomic_sub(<4 x i32> inreg %rsrc, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.buffer.atomic.sub(i32 %data, <4 x i32> %rsrc, i32 0, i32 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.buffer.atomic.smin(
+define float @buffer_atomic_smin(<4 x i32> inreg %rsrc, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.buffer.atomic.smin(i32 %data, <4 x i32> %rsrc, i32 0, i32 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.buffer.atomic.umin(
+define float @buffer_atomic_umin(<4 x i32> inreg %rsrc, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.buffer.atomic.umin(i32 %data, <4 x i32> %rsrc, i32 0, i32 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.buffer.atomic.smax(
+define float @buffer_atomic_smax(<4 x i32> inreg %rsrc, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.buffer.atomic.smax(i32 %data, <4 x i32> %rsrc, i32 0, i32 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.buffer.atomic.umax(
+define float @buffer_atomic_umax(<4 x i32> inreg %rsrc, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.buffer.atomic.umax(i32 %data, <4 x i32> %rsrc, i32 0, i32 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.buffer.atomic.and(
+define float @buffer_atomic_and(<4 x i32> inreg %rsrc, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.buffer.atomic.and(i32 %data, <4 x i32> %rsrc, i32 0, i32 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.buffer.atomic.or(
+define float @buffer_atomic_or(<4 x i32> inreg %rsrc, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.buffer.atomic.or(i32 %data, <4 x i32> %rsrc, i32 0, i32 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.buffer.atomic.xor(
+define float @buffer_atomic_xor(<4 x i32> inreg %rsrc, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.buffer.atomic.xor(i32 %data, <4 x i32> %rsrc, i32 0, i32 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.buffer.atomic.cmpswap(
+define float @buffer_atomic_cmpswap(<4 x i32> inreg %rsrc, i32 inreg %data, i32 inreg %cmp) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.buffer.atomic.cmpswap(i32 %data, i32 %cmp, <4 x i32> %rsrc, i32 0, i32 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+declare i32 @llvm.amdgcn.buffer.atomic.swap(i32, <4 x i32>, i32, i32, i1) #0
+declare i32 @llvm.amdgcn.buffer.atomic.add(i32, <4 x i32>, i32, i32, i1) #0
+declare i32 @llvm.amdgcn.buffer.atomic.sub(i32, <4 x i32>, i32, i32, i1) #0
+declare i32 @llvm.amdgcn.buffer.atomic.smin(i32, <4 x i32>, i32, i32, i1) #0
+declare i32 @llvm.amdgcn.buffer.atomic.umin(i32, <4 x i32>, i32, i32, i1) #0
+declare i32 @llvm.amdgcn.buffer.atomic.smax(i32, <4 x i32>, i32, i32, i1) #0
+declare i32 @llvm.amdgcn.buffer.atomic.umax(i32, <4 x i32>, i32, i32, i1) #0
+declare i32 @llvm.amdgcn.buffer.atomic.and(i32, <4 x i32>, i32, i32, i1) #0
+declare i32 @llvm.amdgcn.buffer.atomic.or(i32, <4 x i32>, i32, i32, i1) #0
+declare i32 @llvm.amdgcn.buffer.atomic.xor(i32, <4 x i32>, i32, i32, i1) #0
+declare i32 @llvm.amdgcn.buffer.atomic.cmpswap(i32, i32, <4 x i32>, i32, i32, i1) #0
+
+attributes #0 = { nounwind }
diff --git a/test/Analysis/DivergenceAnalysis/AMDGPU/llvm.amdgcn.image.atomic.ll b/test/Analysis/DivergenceAnalysis/AMDGPU/llvm.amdgcn.image.atomic.ll
new file mode 100644
index 0000000000000..4a3b60f08de2e
--- /dev/null
+++ b/test/Analysis/DivergenceAnalysis/AMDGPU/llvm.amdgcn.image.atomic.ll
@@ -0,0 +1,121 @@
+;RUN: opt -mtriple=amdgcn-mesa-mesa3d -analyze -divergence %s | FileCheck %s
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.image.atomic.swap.i32(
+define float @image_atomic_swap(<8 x i32> inreg %rsrc, i32 inreg %addr, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.image.atomic.swap.i32(i32 %data, i32 %addr, <8 x i32> %rsrc, i1 0, i1 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.image.atomic.add.i32(
+define float @image_atomic_add(<8 x i32> inreg %rsrc, i32 inreg %addr, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.image.atomic.add.i32(i32 %data, i32 %addr, <8 x i32> %rsrc, i1 0, i1 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.image.atomic.sub.i32(
+define float @image_atomic_sub(<8 x i32> inreg %rsrc, i32 inreg %addr, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.image.atomic.sub.i32(i32 %data, i32 %addr, <8 x i32> %rsrc, i1 0, i1 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.image.atomic.smin.i32(
+define float @image_atomic_smin(<8 x i32> inreg %rsrc, i32 inreg %addr, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.image.atomic.smin.i32(i32 %data, i32 %addr, <8 x i32> %rsrc, i1 0, i1 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.image.atomic.umin.i32(
+define float @image_atomic_umin(<8 x i32> inreg %rsrc, i32 inreg %addr, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.image.atomic.umin.i32(i32 %data, i32 %addr, <8 x i32> %rsrc, i1 0, i1 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.image.atomic.smax.i32(
+define float @image_atomic_smax(<8 x i32> inreg %rsrc, i32 inreg %addr, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.image.atomic.smax.i32(i32 %data, i32 %addr, <8 x i32> %rsrc, i1 0, i1 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.image.atomic.umax.i32(
+define float @image_atomic_umax(<8 x i32> inreg %rsrc, i32 inreg %addr, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.image.atomic.umax.i32(i32 %data, i32 %addr, <8 x i32> %rsrc, i1 0, i1 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.image.atomic.and.i32(
+define float @image_atomic_and(<8 x i32> inreg %rsrc, i32 inreg %addr, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.image.atomic.and.i32(i32 %data, i32 %addr, <8 x i32> %rsrc, i1 0, i1 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.image.atomic.or.i32(
+define float @image_atomic_or(<8 x i32> inreg %rsrc, i32 inreg %addr, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.image.atomic.or.i32(i32 %data, i32 %addr, <8 x i32> %rsrc, i1 0, i1 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.image.atomic.xor.i32(
+define float @image_atomic_xor(<8 x i32> inreg %rsrc, i32 inreg %addr, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.image.atomic.xor.i32(i32 %data, i32 %addr, <8 x i32> %rsrc, i1 0, i1 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.image.atomic.inc.i32(
+define float @image_atomic_inc(<8 x i32> inreg %rsrc, i32 inreg %addr, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.image.atomic.inc.i32(i32 %data, i32 %addr, <8 x i32> %rsrc, i1 0, i1 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.image.atomic.dec.i32(
+define float @image_atomic_dec(<8 x i32> inreg %rsrc, i32 inreg %addr, i32 inreg %data) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.image.atomic.dec.i32(i32 %data, i32 %addr, <8 x i32> %rsrc, i1 0, i1 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+;CHECK: DIVERGENT: %orig = call i32 @llvm.amdgcn.image.atomic.cmpswap.i32(
+define float @image_atomic_cmpswap(<8 x i32> inreg %rsrc, i32 inreg %addr, i32 inreg %data, i32 inreg %cmp) #0 {
+main_body:
+ %orig = call i32 @llvm.amdgcn.image.atomic.cmpswap.i32(i32 %data, i32 %cmp, i32 %addr, <8 x i32> %rsrc, i1 0, i1 0, i1 0)
+ %r = bitcast i32 %orig to float
+ ret float %r
+}
+
+declare i32 @llvm.amdgcn.image.atomic.swap.i32(i32, i32, <8 x i32>, i1, i1, i1) #0
+declare i32 @llvm.amdgcn.image.atomic.add.i32(i32, i32, <8 x i32>, i1, i1, i1) #0
+declare i32 @llvm.amdgcn.image.atomic.sub.i32(i32, i32, <8 x i32>, i1, i1, i1) #0
+declare i32 @llvm.amdgcn.image.atomic.smin.i32(i32, i32, <8 x i32>, i1, i1, i1) #0
+declare i32 @llvm.amdgcn.image.atomic.umin.i32(i32, i32, <8 x i32>, i1, i1, i1) #0
+declare i32 @llvm.amdgcn.image.atomic.smax.i32(i32, i32, <8 x i32>, i1, i1, i1) #0
+declare i32 @llvm.amdgcn.image.atomic.umax.i32(i32, i32, <8 x i32>, i1, i1, i1) #0
+declare i32 @llvm.amdgcn.image.atomic.and.i32(i32, i32, <8 x i32>, i1, i1, i1) #0
+declare i32 @llvm.amdgcn.image.atomic.or.i32(i32, i32, <8 x i32>, i1, i1, i1) #0
+declare i32 @llvm.amdgcn.image.atomic.xor.i32(i32, i32, <8 x i32>, i1, i1, i1) #0
+declare i32 @llvm.amdgcn.image.atomic.inc.i32(i32, i32, <8 x i32>, i1, i1, i1) #0
+declare i32 @llvm.amdgcn.image.atomic.dec.i32(i32, i32, <8 x i32>, i1, i1, i1) #0
+declare i32 @llvm.amdgcn.image.atomic.cmpswap.i32(i32, i32, i32, <8 x i32>,i1, i1, i1) #0
+
+attributes #0 = { nounwind }
diff --git a/test/Analysis/DivergenceAnalysis/AMDGPU/no-return-blocks.ll b/test/Analysis/DivergenceAnalysis/AMDGPU/no-return-blocks.ll
new file mode 100644
index 0000000000000..b4fa79a6ba9f9
--- /dev/null
+++ b/test/Analysis/DivergenceAnalysis/AMDGPU/no-return-blocks.ll
@@ -0,0 +1,30 @@
+; RUN: opt %s -mtriple amdgcn-- -analyze -divergence | FileCheck %s
+
+; CHECK: DIVERGENT: %tmp5 = getelementptr inbounds float, float addrspace(1)* %arg, i64 %tmp2
+; CHECK: DIVERGENT: %tmp10 = load volatile float, float addrspace(1)* %tmp5, align 4
+; CHECK: DIVERGENT: %tmp11 = load volatile float, float addrspace(1)* %tmp5, align 4
+
+; The post dominator tree does not have a root node in this case
+define void @no_return_blocks(float addrspace(1)* noalias nocapture readonly %arg, float addrspace(1)* noalias nocapture readonly %arg1) #0 {
+bb0:
+ %tmp = tail call i32 @llvm.amdgcn.workitem.id.x() #0
+ %tmp2 = sext i32 %tmp to i64
+ %tmp5 = getelementptr inbounds float, float addrspace(1)* %arg, i64 %tmp2
+ %tmp6 = load volatile float, float addrspace(1)* %tmp5, align 4
+ %tmp8 = fcmp olt float %tmp6, 0.000000e+00
+ br i1 %tmp8, label %bb1, label %bb2
+
+bb1:
+ %tmp10 = load volatile float, float addrspace(1)* %tmp5, align 4
+ br label %bb2
+
+bb2:
+ %tmp11 = load volatile float, float addrspace(1)* %tmp5, align 4
+ br label %bb1
+}
+
+; Function Attrs: nounwind readnone
+declare i32 @llvm.amdgcn.workitem.id.x() #1
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone }
diff --git a/test/Analysis/DivergenceAnalysis/AMDGPU/phi-undef.ll b/test/Analysis/DivergenceAnalysis/AMDGPU/phi-undef.ll
new file mode 100644
index 0000000000000..da9c3a9391be4
--- /dev/null
+++ b/test/Analysis/DivergenceAnalysis/AMDGPU/phi-undef.ll
@@ -0,0 +1,28 @@
+; RUN: opt -mtriple=amdgcn-- -analyze -divergence %s | FileCheck %s
+
+; CHECK-LABEL: 'test1':
+; CHECK-NEXT: DIVERGENT: i32 %bound
+; CHECK-NEXT: DIVERGENT: %break = icmp sge i32 %counter, %bound
+; CHECK-NEXT: DIVERGENT: br i1 %break, label %footer, label %body
+; CHECK-NEXT: DIVERGENT: br i1 %break, label %end, label %header
+; Note: %counter is not divergent!
+define amdgpu_ps void @test1(i32 %bound) {
+entry:
+ br label %header
+
+header:
+ %counter = phi i32 [ 0, %entry ], [ %counter.footer, %footer ]
+ %break = icmp sge i32 %counter, %bound
+ br i1 %break, label %footer, label %body
+
+body:
+ %counter.next = add i32 %counter, 1
+ br label %footer
+
+footer:
+ %counter.footer = phi i32 [ %counter.next, %body ], [ undef, %header ]
+ br i1 %break, label %end, label %header
+
+end:
+ ret void
+}
diff --git a/test/Analysis/DivergenceAnalysis/AMDGPU/unreachable-loop-block.ll b/test/Analysis/DivergenceAnalysis/AMDGPU/unreachable-loop-block.ll
new file mode 100644
index 0000000000000..ca93dda2c5739
--- /dev/null
+++ b/test/Analysis/DivergenceAnalysis/AMDGPU/unreachable-loop-block.ll
@@ -0,0 +1,17 @@
+; RUN: opt %s -mtriple amdgcn-- -analyze -divergence | FileCheck %s
+
+; CHECK: DIVERGENT: %tmp = cmpxchg volatile
+define void @unreachable_loop(i32 %tidx) #0 {
+entry:
+ unreachable
+
+unreachable_loop: ; preds = %do.body.i, %if.then11
+ %tmp = cmpxchg volatile i32 addrspace(1)* null, i32 0, i32 0 seq_cst seq_cst
+ %cmp.i = extractvalue { i32, i1 } %tmp, 1
+ br i1 %cmp.i, label %unreachable_loop, label %end
+
+end: ; preds = %do.body.i51, %atomicAdd_g_f.exit
+ unreachable
+}
+
+attributes #0 = { norecurse nounwind }
diff --git a/test/Analysis/DivergenceAnalysis/AMDGPU/workitem-intrinsics.ll b/test/Analysis/DivergenceAnalysis/AMDGPU/workitem-intrinsics.ll
new file mode 100644
index 0000000000000..669ee802c516b
--- /dev/null
+++ b/test/Analysis/DivergenceAnalysis/AMDGPU/workitem-intrinsics.ll
@@ -0,0 +1,45 @@
+; RUN: opt -mtriple amdgcn-unknown-amdhsa -analyze -divergence %s | FileCheck %s
+
+declare i32 @llvm.amdgcn.workitem.id.x() #0
+declare i32 @llvm.amdgcn.workitem.id.y() #0
+declare i32 @llvm.amdgcn.workitem.id.z() #0
+declare i32 @llvm.amdgcn.mbcnt.lo(i32, i32) #0
+declare i32 @llvm.amdgcn.mbcnt.hi(i32, i32) #0
+
+; CHECK: DIVERGENT: %id.x = call i32 @llvm.amdgcn.workitem.id.x()
+define void @workitem_id_x() #1 {
+ %id.x = call i32 @llvm.amdgcn.workitem.id.x()
+ store volatile i32 %id.x, i32 addrspace(1)* undef
+ ret void
+}
+
+; CHECK: DIVERGENT: %id.y = call i32 @llvm.amdgcn.workitem.id.y()
+define void @workitem_id_y() #1 {
+ %id.y = call i32 @llvm.amdgcn.workitem.id.y()
+ store volatile i32 %id.y, i32 addrspace(1)* undef
+ ret void
+}
+
+; CHECK: DIVERGENT: %id.z = call i32 @llvm.amdgcn.workitem.id.z()
+define void @workitem_id_z() #1 {
+ %id.z = call i32 @llvm.amdgcn.workitem.id.z()
+ store volatile i32 %id.z, i32 addrspace(1)* undef
+ ret void
+}
+
+; CHECK: DIVERGENT: %mbcnt.lo = call i32 @llvm.amdgcn.mbcnt.lo(i32 0, i32 0)
+define void @mbcnt_lo() #1 {
+ %mbcnt.lo = call i32 @llvm.amdgcn.mbcnt.lo(i32 0, i32 0)
+ store volatile i32 %mbcnt.lo, i32 addrspace(1)* undef
+ ret void
+}
+
+; CHECK: DIVERGENT: %mbcnt.hi = call i32 @llvm.amdgcn.mbcnt.hi(i32 0, i32 0)
+define void @mbcnt_hi() #1 {
+ %mbcnt.hi = call i32 @llvm.amdgcn.mbcnt.hi(i32 0, i32 0)
+ store volatile i32 %mbcnt.hi, i32 addrspace(1)* undef
+ ret void
+}
+
+attributes #0 = { nounwind readnone }
+attributes #1 = { nounwind }
diff --git a/test/Analysis/DivergenceAnalysis/NVPTX/diverge.ll b/test/Analysis/DivergenceAnalysis/NVPTX/diverge.ll
index fc63038e77cc1..cbfd2901442b4 100644
--- a/test/Analysis/DivergenceAnalysis/NVPTX/diverge.ll
+++ b/test/Analysis/DivergenceAnalysis/NVPTX/diverge.ll
@@ -100,7 +100,7 @@ merge:
define i32 @loop() {
; CHECK-LABEL: Printing analysis 'Divergence Analysis' for function 'loop'
entry:
- %laneid = call i32 @llvm.ptx.read.laneid()
+ %laneid = call i32 @llvm.nvvm.read.ptx.sreg.laneid()
br label %loop
loop:
%i = phi i32 [ 0, %entry ], [ %i1, %loop ]
@@ -208,7 +208,7 @@ bb3:
declare i32 @llvm.nvvm.read.ptx.sreg.tid.x()
declare i32 @llvm.nvvm.read.ptx.sreg.tid.y()
declare i32 @llvm.nvvm.read.ptx.sreg.tid.z()
-declare i32 @llvm.ptx.read.laneid()
+declare i32 @llvm.nvvm.read.ptx.sreg.laneid()
!nvvm.annotations = !{!0, !1, !2, !3, !4, !5}
!0 = !{i32 (i32, i32, i32)* @no_diverge, !"kernel", i32 1}
diff --git a/test/Analysis/DominanceFrontier/new_pm_test.ll b/test/Analysis/DominanceFrontier/new_pm_test.ll
new file mode 100644
index 0000000000000..7ab1fca80532a
--- /dev/null
+++ b/test/Analysis/DominanceFrontier/new_pm_test.ll
@@ -0,0 +1,50 @@
+; REQUIRES: asserts
+; RUN: opt < %s -passes='print<domfrontier>' 2>&1 | FileCheck %s
+
+define void @a_linear_impl_fig_1() nounwind {
+0:
+ br label %"1"
+1:
+ br label %"2"
+2:
+ br label %"3"
+3:
+ br i1 1, label %"13", label %"4"
+4:
+ br i1 1, label %"5", label %"1"
+5:
+ br i1 1, label %"8", label %"6"
+6:
+ br i1 1, label %"7", label %"4"
+7:
+ ret void
+8:
+ br i1 1, label %"9", label %"1"
+9:
+ br label %"10"
+10:
+ br i1 1, label %"12", label %"11"
+11:
+ br i1 1, label %"9", label %"8"
+13:
+ br i1 1, label %"2", label %"1"
+12:
+ switch i32 0, label %"1" [ i32 0, label %"9"
+ i32 1, label %"8"]
+}
+
+; CHECK: DominanceFrontier for function: a_linear_impl_fig_1
+; CHECK-DAG: DomFrontier for BB %"0" is:
+; CHECK-DAG: DomFrontier for BB %"11" is: %"{{[8|9]}}" %"{{[8|9]}}"
+; CHECK-DAG: DomFrontier for BB %"1" is: %"1"
+; CHECK-DAG: DomFrontier for BB %"2" is: %"{{[1|2]}}" %"{{[1|2]}}"
+; CHECK-DAG: DomFrontier for BB %"3" is: %"{{[1|2]}}" %"{{[1|2]}}"
+; CHECK-DAG: DomFrontier for BB %"13" is: %"{{[1|2]}}" %"{{[1|2]}}"
+; CHECK-DAG: DomFrontier for BB %"4" is: %"{{[1|4]}}" %"{{[1|4]}}"
+; CHECK-DAG: DomFrontier for BB %"5" is: %"{{[1|4]}}" %"{{[1|4]}}"
+; CHECK-DAG: DomFrontier for BB %"8" is: %"{{[1|8]}}" %"{{[1|8]}}"
+; CHECK-DAG: DomFrontier for BB %"6" is: %"4"
+; CHECK-DAG: DomFrontier for BB %"7" is:
+; CHECK-DAG: DomFrontier for BB %"9" is: %"{{[1|8|9]}}" %"{{[1|8|9]}}" %"{{[1|8|9]}}"
+; CHECK-DAG: DomFrontier for BB %"10" is: %"{{[1|8|9]}}" %"{{[1|8|9]}}" %"{{[1|8|9]}}"
+; CHECK-DAG: DomFrontier for BB %"12" is: %"{{[1|8|9]}}" %"{{[1|8|9]}}" %"{{[1|8|9]}}"
diff --git a/test/Analysis/GlobalsModRef/aliastest.ll b/test/Analysis/GlobalsModRef/aliastest.ll
index ecc6bcc55d1dc..3a0eee84e881c 100644
--- a/test/Analysis/GlobalsModRef/aliastest.ll
+++ b/test/Analysis/GlobalsModRef/aliastest.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -basicaa -globals-aa -gvn -S -enable-unsafe-globalsmodref-alias-results | FileCheck %s
+; RUN: opt < %s -aa-pipeline=basic-aa,globals-aa -passes="require<globals-aa>,function(gvn)" -S -enable-unsafe-globalsmodref-alias-results | FileCheck %s
;
; Note that this test relies on an unsafe feature of GlobalsModRef. While this
; test is correct and safe, GMR's technique for handling this isn't generally.
diff --git a/test/Analysis/GlobalsModRef/comdat-ipo.ll b/test/Analysis/GlobalsModRef/comdat-ipo.ll
new file mode 100644
index 0000000000000..a9cc821e7afb2
--- /dev/null
+++ b/test/Analysis/GlobalsModRef/comdat-ipo.ll
@@ -0,0 +1,21 @@
+; RUN: opt < %s -basicaa -globals-aa -gvn -S | FileCheck %s
+
+; See PR26774
+
+@X = internal global i32 4
+
+define i32 @test(i32* %P) {
+; CHECK: @test
+; CHECK-NEXT: store i32 12, i32* @X
+; CHECK-NEXT: call void @doesnotmodX()
+; CHECK-NEXT: %V = load i32, i32* @X
+; CHECK-NEXT: ret i32 %V
+ store i32 12, i32* @X
+ call void @doesnotmodX( )
+ %V = load i32, i32* @X
+ ret i32 %V
+}
+
+define linkonce_odr void @doesnotmodX() {
+ ret void
+}
diff --git a/test/Analysis/GlobalsModRef/func-memattributes.ll b/test/Analysis/GlobalsModRef/func-memattributes.ll
new file mode 100644
index 0000000000000..5494512592e33
--- /dev/null
+++ b/test/Analysis/GlobalsModRef/func-memattributes.ll
@@ -0,0 +1,31 @@
+; RUN: opt < %s -disable-basicaa -globals-aa -dse -S | FileCheck %s
+
+@X = internal global i32 4
+
+define void @test0() {
+; CHECK-LABEL: @test0
+; CHECK: store i32 0, i32* @X
+; CHECK-NEXT: call void @func_readonly() #0
+; CHECK-NEXT: store i32 1, i32* @X
+ store i32 0, i32* @X
+ call void @func_readonly() #0
+ store i32 1, i32* @X
+ ret void
+}
+
+define void @test1() {
+; CHECK-LABEL: @test1
+; CHECK-NOT: store
+; CHECK: call void @func_read_argmem_only() #1
+; CHECK-NEXT: store i32 3, i32* @X
+ store i32 2, i32* @X
+ call void @func_read_argmem_only() #1
+ store i32 3, i32* @X
+ ret void
+}
+
+declare void @func_readonly() #0
+declare void @func_read_argmem_only() #1
+
+attributes #0 = { readonly }
+attributes #1 = { readonly argmemonly }
diff --git a/test/Analysis/GlobalsModRef/indirect-global.ll b/test/Analysis/GlobalsModRef/indirect-global.ll
index a51f54b075032..39d5260b950ac 100644
--- a/test/Analysis/GlobalsModRef/indirect-global.ll
+++ b/test/Analysis/GlobalsModRef/indirect-global.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -basicaa -globals-aa -gvn -instcombine -S -enable-unsafe-globalsmodref-alias-results | FileCheck %s
+; RUN: opt < %s -aa-pipeline=basic-aa,globals-aa -passes="require<globals-aa>,function(gvn,instcombine)" -S -enable-unsafe-globalsmodref-alias-results | FileCheck %s
;
; Note that this test relies on an unsafe feature of GlobalsModRef. While this
; test is correct and safe, GMR's technique for handling this isn't generally.
diff --git a/test/Analysis/GlobalsModRef/no-escape.ll b/test/Analysis/GlobalsModRef/no-escape.ll
new file mode 100644
index 0000000000000..d813a92268c69
--- /dev/null
+++ b/test/Analysis/GlobalsModRef/no-escape.ll
@@ -0,0 +1,65 @@
+; RUN: opt < %s -basicaa -globals-aa -S -enable-non-lto-gmr=true -licm | FileCheck %s
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.10.0"
+
+@b = common global i32 0, align 4
+@c = internal global i32 0, align 4
+@d = common global i32 0, align 4
+@e = common global i32* null, align 4
+
+define void @foo(i32* %P) noinline {
+; CHECK: define void @foo
+ %loadp = load i32, i32* %P, align 4
+ store i32 %loadp, i32* @d, align 4
+ ret void
+}
+
+define void @bar() noinline {
+; CHECK: define void @bar
+ %loadp = load i32, i32* @d, align 4
+ store i32 %loadp, i32* @c, align 4
+ ret void
+}
+
+define i32 @main() {
+entry:
+ %retval = alloca i32, align 4
+ %c = alloca [1 x i32], align 4
+ store i32 0, i32* %retval, align 4
+ call void @bar()
+ store i32 0, i32* @b, align 4
+ br label %for.cond
+ ;; Check that @c is LICM'ed out.
+; CHECK: load i32, i32* @c
+for.cond: ; preds = %for.inc, %entry
+; CHECK-LABEL: for.cond:
+; CHECK: load i32, i32* @b
+ %a1 = load i32, i32* @b, align 4
+ %aa2 = load i32, i32* @c, align 4
+ %add = add nsw i32 %a1, %aa2
+ %p1 = load i32*, i32** @e, align 4
+ call void @foo(i32* %p1)
+ %cmp = icmp slt i32 %add, 3
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %a2 = load i32, i32* @b, align 4
+ %idxprom = sext i32 %a2 to i64
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %a3 = load i32, i32* @b, align 4
+ %inc = add nsw i32 %a3, 1
+ store i32 %inc, i32* @b, align 4
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret i32 0
+}
+
+; Function Attrs: nounwind argmemonly
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind argmemonly
+
+; Function Attrs: noreturn nounwind
+declare void @abort() noreturn nounwind
diff --git a/test/Analysis/LazyCallGraph/basic.ll b/test/Analysis/LazyCallGraph/basic.ll
index fce453bc15de7..0d05a7a6514ec 100644
--- a/test/Analysis/LazyCallGraph/basic.ll
+++ b/test/Analysis/LazyCallGraph/basic.ll
@@ -1,9 +1,9 @@
-; RUN: opt -disable-output -passes=print-cg %s 2>&1 | FileCheck %s
+; RUN: opt -disable-output -passes=print-lcg %s 2>&1 | FileCheck %s
;
; Basic validation of the call graph analysis used in the new pass manager.
define void @f() {
-; CHECK-LABEL: Call edges in function: f
+; CHECK-LABEL: Edges in function: f
; CHECK-NOT: ->
entry:
@@ -51,8 +51,8 @@ define void @f12() {
declare i32 @__gxx_personality_v0(...)
define void @test0() {
-; CHECK-LABEL: Call edges in function: test0
-; CHECK-NEXT: -> f
+; CHECK-LABEL: Edges in function: test0
+; CHECK-NEXT: call -> f
; CHECK-NOT: ->
entry:
@@ -64,19 +64,19 @@ entry:
}
define void ()* @test1(void ()** %x) personality i32 (...)* @__gxx_personality_v0 {
-; CHECK-LABEL: Call edges in function: test1
-; CHECK-NEXT: -> f12
-; CHECK-NEXT: -> f11
-; CHECK-NEXT: -> f10
-; CHECK-NEXT: -> f7
-; CHECK-NEXT: -> f9
-; CHECK-NEXT: -> f8
-; CHECK-NEXT: -> f6
-; CHECK-NEXT: -> f5
-; CHECK-NEXT: -> f4
-; CHECK-NEXT: -> f3
-; CHECK-NEXT: -> f2
-; CHECK-NEXT: -> f1
+; CHECK-LABEL: Edges in function: test1
+; CHECK-NEXT: call -> f6
+; CHECK-NEXT: call -> f10
+; CHECK-NEXT: ref -> f12
+; CHECK-NEXT: ref -> f11
+; CHECK-NEXT: ref -> f7
+; CHECK-NEXT: ref -> f9
+; CHECK-NEXT: ref -> f8
+; CHECK-NEXT: ref -> f5
+; CHECK-NEXT: ref -> f4
+; CHECK-NEXT: ref -> f3
+; CHECK-NEXT: ref -> f2
+; CHECK-NEXT: ref -> f1
; CHECK-NOT: ->
entry:
@@ -108,14 +108,14 @@ unwind:
@h = constant void ()* @f7
define void @test2() {
-; CHECK-LABEL: Call edges in function: test2
-; CHECK-NEXT: -> f7
-; CHECK-NEXT: -> f6
-; CHECK-NEXT: -> f5
-; CHECK-NEXT: -> f4
-; CHECK-NEXT: -> f3
-; CHECK-NEXT: -> f2
-; CHECK-NEXT: -> f1
+; CHECK-LABEL: Edges in function: test2
+; CHECK-NEXT: ref -> f7
+; CHECK-NEXT: ref -> f6
+; CHECK-NEXT: ref -> f5
+; CHECK-NEXT: ref -> f4
+; CHECK-NEXT: ref -> f3
+; CHECK-NEXT: ref -> f2
+; CHECK-NEXT: ref -> f1
; CHECK-NOT: ->
load i8*, i8** bitcast (void ()** @g to i8**)
@@ -125,52 +125,219 @@ define void @test2() {
ret void
}
+@test3_ptr = external global void ()*
+
+define void @test3_aa1() {
+; CHECK-LABEL: Edges in function: test3_aa1
+; CHECK-NEXT: call -> test3_aa2
+; CHECK-NEXT: ref -> test3_ab1
+; CHECK-NOT: ->
+
+entry:
+ call void @test3_aa2()
+ store void ()* @test3_ab1, void ()** @test3_ptr
+ ret void
+}
+
+define void @test3_aa2() {
+; CHECK-LABEL: Edges in function: test3_aa2
+; CHECK-NEXT: call -> test3_aa1
+; CHECK-NEXT: call -> test3_ab2
+; CHECK-NOT: ->
+
+entry:
+ call void @test3_aa1()
+ call void @test3_ab2()
+ ret void
+}
+
+define void @test3_ab1() {
+; CHECK-LABEL: Edges in function: test3_ab1
+; CHECK-NEXT: call -> test3_ab2
+; CHECK-NEXT: call -> test3_ac1
+; CHECK-NOT: ->
+
+entry:
+ call void @test3_ab2()
+ call void @test3_ac1()
+ ret void
+}
+
+define void @test3_ab2() {
+; CHECK-LABEL: Edges in function: test3_ab2
+; CHECK-NEXT: call -> test3_ab1
+; CHECK-NEXT: call -> test3_ba1
+; CHECK-NOT: ->
+
+entry:
+ call void @test3_ab1()
+ call void @test3_ba1()
+ ret void
+}
+
+define void @test3_ac1() {
+; CHECK-LABEL: Edges in function: test3_ac1
+; CHECK-NEXT: call -> test3_ac2
+; CHECK-NEXT: ref -> test3_aa2
+; CHECK-NOT: ->
+
+entry:
+ call void @test3_ac2()
+ store void ()* @test3_aa2, void ()** @test3_ptr
+ ret void
+}
+
+define void @test3_ac2() {
+; CHECK-LABEL: Edges in function: test3_ac2
+; CHECK-NEXT: call -> test3_ac1
+; CHECK-NEXT: ref -> test3_ba1
+; CHECK-NOT: ->
+
+entry:
+ call void @test3_ac1()
+ store void ()* @test3_ba1, void ()** @test3_ptr
+ ret void
+}
+
+define void @test3_ba1() {
+; CHECK-LABEL: Edges in function: test3_ba1
+; CHECK-NEXT: call -> test3_bb1
+; CHECK-NEXT: ref -> test3_ca1
+; CHECK-NOT: ->
+
+entry:
+ call void @test3_bb1()
+ store void ()* @test3_ca1, void ()** @test3_ptr
+ ret void
+}
+
+define void @test3_bb1() {
+; CHECK-LABEL: Edges in function: test3_bb1
+; CHECK-NEXT: call -> test3_ca2
+; CHECK-NEXT: ref -> test3_ba1
+; CHECK-NOT: ->
+
+entry:
+ call void @test3_ca2()
+ store void ()* @test3_ba1, void ()** @test3_ptr
+ ret void
+}
+
+define void @test3_ca1() {
+; CHECK-LABEL: Edges in function: test3_ca1
+; CHECK-NEXT: call -> test3_ca2
+; CHECK-NOT: ->
+
+entry:
+ call void @test3_ca2()
+ ret void
+}
+
+define void @test3_ca2() {
+; CHECK-LABEL: Edges in function: test3_ca2
+; CHECK-NEXT: call -> test3_ca3
+; CHECK-NOT: ->
+
+entry:
+ call void @test3_ca3()
+ ret void
+}
+
+define void @test3_ca3() {
+; CHECK-LABEL: Edges in function: test3_ca3
+; CHECK-NEXT: call -> test3_ca1
+; CHECK-NOT: ->
+
+entry:
+ call void @test3_ca1()
+ ret void
+}
+
; Verify the SCCs formed.
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: f7
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 3 functions:
+; CHECK-NEXT: test3_ca3
+; CHECK-NEXT: test3_ca1
+; CHECK-NEXT: test3_ca2
+;
+; CHECK-LABEL: RefSCC with 2 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: test3_bb1
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: test3_ba1
+;
+; CHECK-LABEL: RefSCC with 3 call SCCs:
+; CHECK-NEXT: SCC with 2 functions:
+; CHECK-NEXT: test3_ac2
+; CHECK-NEXT: test3_ac1
+; CHECK-NEXT: SCC with 2 functions:
+; CHECK-NEXT: test3_ab2
+; CHECK-NEXT: test3_ab1
+; CHECK-NEXT: SCC with 2 functions:
+; CHECK-NEXT: test3_aa2
+; CHECK-NEXT: test3_aa1
+;
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: f7
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: f6
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: f6
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: f5
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: f5
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: f4
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: f4
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: f3
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: f3
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: f2
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: f2
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: f1
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: f1
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: test2
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: test2
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: f12
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: f10
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: f11
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: f12
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: f10
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: f11
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: f9
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: f9
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: f8
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: f8
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: test1
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: test1
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: f
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: f
;
-; CHECK-LABEL: SCC with 1 functions:
-; CHECK-NEXT: test0
+; CHECK-LABEL: RefSCC with 1 call SCCs:
+; CHECK-NEXT: SCC with 1 functions:
+; CHECK-NEXT: test0
diff --git a/test/Analysis/LazyCallGraph/non-leaf-intrinsics.ll b/test/Analysis/LazyCallGraph/non-leaf-intrinsics.ll
index 89a21e542f747..f5dc72ff9e97e 100644
--- a/test/Analysis/LazyCallGraph/non-leaf-intrinsics.ll
+++ b/test/Analysis/LazyCallGraph/non-leaf-intrinsics.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -disable-output -passes=print-cg < %s 2>&1 | FileCheck %s
+; RUN: opt -S -disable-output -passes=print-lcg < %s 2>&1 | FileCheck %s
declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
@@ -8,7 +8,7 @@ define private void @f() {
}
define void @calls_statepoint(i8 addrspace(1)* %arg) gc "statepoint-example" {
-; CHECK: Call edges in function: calls_statepoint
+; CHECK: Edges in function: calls_statepoint
; CHECK-NEXT: -> f
entry:
%cast = bitcast i8 addrspace(1)* %arg to i64 addrspace(1)*
@@ -17,7 +17,7 @@ entry:
}
define void @calls_patchpoint() {
-; CHECK: Call edges in function: calls_patchpoint
+; CHECK: Edges in function: calls_patchpoint
; CHECK-NEXT: -> f
entry:
%c = bitcast void()* @f to i8*
diff --git a/test/Analysis/LoopAccessAnalysis/backward-dep-different-types.ll b/test/Analysis/LoopAccessAnalysis/backward-dep-different-types.ll
index 5d4fb7d3d66cb..d8040a31a8dc3 100644
--- a/test/Analysis/LoopAccessAnalysis/backward-dep-different-types.ll
+++ b/test/Analysis/LoopAccessAnalysis/backward-dep-different-types.ll
@@ -1,4 +1,5 @@
; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
; In this loop just because we access A through different types (int, float)
; we still have a dependence cycle:
diff --git a/test/Analysis/LoopAccessAnalysis/forward-loop-carried.ll b/test/Analysis/LoopAccessAnalysis/forward-loop-carried.ll
index e18ec2357fdb2..7d3ac09dbb9c4 100644
--- a/test/Analysis/LoopAccessAnalysis/forward-loop-carried.ll
+++ b/test/Analysis/LoopAccessAnalysis/forward-loop-carried.ll
@@ -1,4 +1,5 @@
; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
; for (unsigned i = 0; i < 100; i++) {
; A[i+8] = B[i] + 2;
diff --git a/test/Analysis/LoopAccessAnalysis/forward-loop-independent.ll b/test/Analysis/LoopAccessAnalysis/forward-loop-independent.ll
index e1ba674ce80ad..41e2a2904fb2f 100644
--- a/test/Analysis/LoopAccessAnalysis/forward-loop-independent.ll
+++ b/test/Analysis/LoopAccessAnalysis/forward-loop-independent.ll
@@ -1,4 +1,5 @@
; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
; Check that loop-indepedent forward dependences are discovered properly.
;
diff --git a/test/Analysis/LoopAccessAnalysis/independent-interleaved.ll b/test/Analysis/LoopAccessAnalysis/independent-interleaved.ll
new file mode 100644
index 0000000000000..fe56ea9ab5939
--- /dev/null
+++ b/test/Analysis/LoopAccessAnalysis/independent-interleaved.ll
@@ -0,0 +1,46 @@
+; RUN: opt < %s -store-to-load-forwarding-conflict-detection=false -loop-accesses -analyze | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -store-to-load-forwarding-conflict-detection=false -disable-output < %s 2>&1 | FileCheck %s
+
+; This test checks that we prove the strided accesses to be independent before
+; concluding that there is a forward dependence.
+
+; struct pair {
+; int x;
+; int y;
+; };
+;
+; int independent_interleaved(struct pair *p, int z, int n) {
+; int s = 0;
+; for (int i = 0; i < n; i++) {
+; p[i].y = z;
+; s += p[i].x;
+; }
+; return s;
+; }
+
+; CHECK: for.body:
+; CHECK-NOT: Forward:
+; CHECK-NOT: store i32 %z, i32* %p_i.y, align 8 ->
+; CHECK-NOT: %0 = load i32, i32* %p_i.x, align 8
+
+%pair = type { i32, i32 }
+define i32 @independent_interleaved(%pair *%p, i64 %n, i32 %z) {
+entry:
+ br label %for.body
+
+for.body:
+ %i = phi i64 [ %i.next, %for.body ], [ 0, %entry ]
+ %s = phi i32 [ %1, %for.body ], [ 0, %entry ]
+ %p_i.x = getelementptr inbounds %pair, %pair* %p, i64 %i, i32 0
+ %p_i.y = getelementptr inbounds %pair, %pair* %p, i64 %i, i32 1
+ store i32 %z, i32* %p_i.y, align 8
+ %0 = load i32, i32* %p_i.x, align 8
+ %1 = add nsw i32 %0, %s
+ %i.next = add nuw nsw i64 %i, 1
+ %cond = icmp slt i64 %i.next, %n
+ br i1 %cond, label %for.body, label %for.end
+
+for.end:
+ %2 = phi i32 [ %1, %for.body ]
+ ret i32 %2
+}
diff --git a/test/Analysis/LoopAccessAnalysis/memcheck-for-loop-invariant.ll b/test/Analysis/LoopAccessAnalysis/memcheck-for-loop-invariant.ll
new file mode 100644
index 0000000000000..f06bb00ec64aa
--- /dev/null
+++ b/test/Analysis/LoopAccessAnalysis/memcheck-for-loop-invariant.ll
@@ -0,0 +1,39 @@
+; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
+
+; Handle memchecks involving loop-invariant addresses:
+;
+; extern int *A, *b;
+; for (i = 0; i < N; ++i) {
+; A[i] = b;
+; }
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+
+; CHECK: Memory dependences are safe with run-time checks
+; CHECK: Run-time memory checks:
+; CHECK-NEXT: Check 0:
+; CHECK-NEXT: Comparing group ({{.*}}):
+; CHECK-NEXT: %arrayidxA = getelementptr inbounds i32, i32* %a, i64 %ind
+; CHECK-NEXT: Against group ({{.*}}):
+; CHECK-NEXT: i32* %b
+
+define void @f(i32* %a, i32* %b) {
+entry:
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %ind = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+
+ %arrayidxA = getelementptr inbounds i32, i32* %a, i64 %ind
+
+ %loadB = load i32, i32* %b, align 4
+ store i32 %loadB, i32* %arrayidxA, align 4
+
+ %inc = add nuw nsw i64 %ind, 1
+ %exitcond = icmp eq i64 %inc, 20
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret void
+}
diff --git a/test/Analysis/LoopAccessAnalysis/multiple-strides-rt-memory-checks.ll b/test/Analysis/LoopAccessAnalysis/multiple-strides-rt-memory-checks.ll
new file mode 100644
index 0000000000000..87a6c18ab3034
--- /dev/null
+++ b/test/Analysis/LoopAccessAnalysis/multiple-strides-rt-memory-checks.ll
@@ -0,0 +1,68 @@
+; RUN: opt -loop-accesses -analyze -S < %s | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
+
+; This is the test case from PR26314.
+; When we were retrying dependence checking with memchecks only,
+; the loop-invariant access in the inner loop was incorrectly determined to be wrapping
+; because it was not strided in the inner loop.
+
+; #define Z 32
+; typedef struct s {
+; int v1[Z];
+; int v2[Z];
+; int v3[Z][Z];
+; } s;
+;
+; void slow_function (s* const obj) {
+; for (int j=0; j<Z; j++) {
+; for (int k=0; k<Z; k++) {
+; int x = obj->v1[k] + obj->v2[j];
+; obj->v3[j][k] += x;
+; }
+; }
+; }
+
+; CHECK: function 'Test':
+; CHECK: .inner:
+; CHECK-NEXT: Memory dependences are safe
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Run-time memory checks:
+; CHECK: Check 0:
+; CHECK: Check 1:
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct.s = type { [32 x i32], [32 x i32], [32 x [32 x i32]] }
+
+define void @Test(%struct.s* nocapture %obj) #0 {
+ br label %.outer.preheader
+
+
+.outer.preheader:
+ %i = phi i64 [ 0, %0 ], [ %i.next, %.outer ]
+ %1 = getelementptr inbounds %struct.s, %struct.s* %obj, i64 0, i32 1, i64 %i
+ br label %.inner
+
+.exit:
+ ret void
+
+.outer:
+ %i.next = add nuw nsw i64 %i, 1
+ %exitcond.outer = icmp eq i64 %i.next, 32
+ br i1 %exitcond.outer, label %.exit, label %.outer.preheader
+
+.inner:
+ %j = phi i64 [ 0, %.outer.preheader ], [ %j.next, %.inner ]
+ %2 = getelementptr inbounds %struct.s, %struct.s* %obj, i64 0, i32 0, i64 %j
+ %3 = load i32, i32* %2
+ %4 = load i32, i32* %1
+ %5 = add nsw i32 %4, %3
+ %6 = getelementptr inbounds %struct.s, %struct.s* %obj, i64 0, i32 2, i64 %i, i64 %j
+ %7 = load i32, i32* %6
+ %8 = add nsw i32 %5, %7
+ store i32 %8, i32* %6
+ %j.next = add nuw nsw i64 %j, 1
+ %exitcond.inner = icmp eq i64 %j.next, 32
+ br i1 %exitcond.inner, label %.outer, label %.inner
+}
diff --git a/test/Analysis/LoopAccessAnalysis/non-wrapping-pointer.ll b/test/Analysis/LoopAccessAnalysis/non-wrapping-pointer.ll
index 0de1cd1bea6de..94080f05bde26 100644
--- a/test/Analysis/LoopAccessAnalysis/non-wrapping-pointer.ll
+++ b/test/Analysis/LoopAccessAnalysis/non-wrapping-pointer.ll
@@ -1,4 +1,5 @@
; RUN: opt -basicaa -loop-accesses -analyze < %s | FileCheck %s
+; RUN: opt -passes='require<aa>,require<scalar-evolution>,require<aa>,loop(print-access-info)' -aa-pipeline='basic-aa' -disable-output < %s 2>&1 | FileCheck %s
; For this loop:
; for (int i = 0; i < n; i++)
diff --git a/test/Analysis/LoopAccessAnalysis/nullptr.ll b/test/Analysis/LoopAccessAnalysis/nullptr.ll
index a72b48cc352d7..476cf3208c84c 100644
--- a/test/Analysis/LoopAccessAnalysis/nullptr.ll
+++ b/test/Analysis/LoopAccessAnalysis/nullptr.ll
@@ -1,4 +1,5 @@
; RUN: opt -loop-accesses -analyze %s | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
; Test that the loop accesses are proven safe in this case.
; The analyzer uses to be confused by the "diamond" because GetUnderlyingObjects
diff --git a/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll b/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll
index 01b3eda3e123b..a9626f4dc7103 100644
--- a/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll
+++ b/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll
@@ -1,4 +1,5 @@
; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
target triple = "aarch64--linux-gnueabi"
@@ -96,11 +97,11 @@ for.end: ; preds = %for.body
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group {{.*}}[[ZERO]]:
; CHECK-NEXT: (Low: %c High: (78 + %c))
-; CHECK-NEXT: Member: {(2 + %c),+,4}
+; CHECK-NEXT: Member: {(2 + %c)<nsw>,+,4}
; CHECK-NEXT: Member: {%c,+,4}
; CHECK-NEXT: Group {{.*}}[[ONE]]:
; CHECK-NEXT: (Low: %a High: (40 + %a))
-; CHECK-NEXT: Member: {(2 + %a),+,2}
+; CHECK-NEXT: Member: {(2 + %a)<nsw>,+,2}
; CHECK-NEXT: Member: {%a,+,2}
; CHECK-NEXT: Group {{.*}}[[TWO]]:
; CHECK-NEXT: (Low: %b High: (38 + %b))
@@ -168,7 +169,7 @@ for.end: ; preds = %for.body
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group {{.*}}[[ZERO]]:
; CHECK-NEXT: (Low: %c High: (78 + %c))
-; CHECK-NEXT: Member: {(2 + %c),+,4}
+; CHECK-NEXT: Member: {(2 + %c)<nsw>,+,4}
; CHECK-NEXT: Member: {%c,+,4}
; CHECK-NEXT: Group {{.*}}[[ONE]]:
; CHECK-NEXT: (Low: %a High: (40 + %a))
@@ -246,8 +247,8 @@ for.end: ; preds = %for.body
; CHECK-NEXT: %arrayidxA2 = getelementptr i16, i16* %a, i64 %ind2
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group {{.*}}[[ZERO]]:
-; CHECK-NEXT: (Low: ((2 * %offset) + %a) High: (9998 + (2 * %offset) + %a))
-; CHECK-NEXT: Member: {((2 * %offset) + %a),+,2}<nsw><%for.body>
+; CHECK-NEXT: (Low: ((2 * %offset) + %a)<nsw> High: (9998 + (2 * %offset) + %a))
+; CHECK-NEXT: Member: {((2 * %offset) + %a)<nsw>,+,2}<nsw><%for.body>
; CHECK-NEXT: Group {{.*}}[[ONE]]:
; CHECK-NEXT: (Low: %a High: (9998 + %a))
; CHECK-NEXT: Member: {%a,+,2}<%for.body>
diff --git a/test/Analysis/LoopAccessAnalysis/pointer-with-unknown-bounds.ll b/test/Analysis/LoopAccessAnalysis/pointer-with-unknown-bounds.ll
index 20b7fb2c63353..a10b851bcd1a2 100644
--- a/test/Analysis/LoopAccessAnalysis/pointer-with-unknown-bounds.ll
+++ b/test/Analysis/LoopAccessAnalysis/pointer-with-unknown-bounds.ll
@@ -1,4 +1,5 @@
; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/Analysis/LoopAccessAnalysis/resort-to-memchecks-only.ll b/test/Analysis/LoopAccessAnalysis/resort-to-memchecks-only.ll
index 9412028fc7026..921fd4d06314d 100644
--- a/test/Analysis/LoopAccessAnalysis/resort-to-memchecks-only.ll
+++ b/test/Analysis/LoopAccessAnalysis/resort-to-memchecks-only.ll
@@ -1,4 +1,5 @@
; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
; We give up analyzing the dependences in this loop due to non-constant
; distance between A[i+offset] and A[i] and add memchecks to prove
diff --git a/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll b/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll
index 2053e49826b99..607e007f7a2d1 100644
--- a/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll
+++ b/test/Analysis/LoopAccessAnalysis/reverse-memcheck-bounds.ll
@@ -1,4 +1,5 @@
; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
; The runtime memory check code and the access grouping
; algorithm both assume that the start and end values
@@ -15,7 +16,7 @@ target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
target triple = "aarch64--linux-gnueabi"
; CHECK: function 'f':
-; CHECK: (Low: (20000 + %a) High: (60000 + %a))
+; CHECK: (Low: (20000 + %a) High: (60000 + %a)<nsw>)
@B = common global i32* null, align 8
@A = common global i32* null, align 8
@@ -58,7 +59,7 @@ for.end: ; preds = %for.body
; Here it is not obvious what the limits are, since 'step' could be negative.
; CHECK: Low: (-1 + (-1 * ((-60001 + (-1 * %a)) umax (-60001 + (40000 * %step) + (-1 * %a)))))
-; CHECK: High: ((60000 + %a) umax (60000 + (-40000 * %step) + %a))
+; CHECK: High: ((60000 + %a)<nsw> umax (60000 + (-40000 * %step) + %a))
define void @g(i64 %step) {
entry:
diff --git a/test/Analysis/LoopAccessAnalysis/safe-no-checks.ll b/test/Analysis/LoopAccessAnalysis/safe-no-checks.ll
index d85258f75aaef..8018994009957 100644
--- a/test/Analysis/LoopAccessAnalysis/safe-no-checks.ll
+++ b/test/Analysis/LoopAccessAnalysis/safe-no-checks.ll
@@ -1,4 +1,5 @@
; RUN: opt -basicaa -loop-accesses -analyze < %s | FileCheck %s
+; RUN: opt -passes='require<aa>,require<scalar-evolution>,require<aa>,loop(print-access-info)' -aa-pipeline='basic-aa' -disable-output < %s 2>&1 | FileCheck %s
; If the arrays don't alias this loop is safe with no memchecks:
; for (i = 0; i < n; i++)
diff --git a/test/Analysis/LoopAccessAnalysis/safe-with-dep-distance.ll b/test/Analysis/LoopAccessAnalysis/safe-with-dep-distance.ll
new file mode 100644
index 0000000000000..910d49edbb181
--- /dev/null
+++ b/test/Analysis/LoopAccessAnalysis/safe-with-dep-distance.ll
@@ -0,0 +1,38 @@
+; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
+
+; Analyze this loop:
+; for (i = 0; i < n; i++)
+; A[i + 4] = A[i] * 2;
+
+; CHECK: Memory dependences are safe with a maximum dependence distance of 8 bytes
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.10.0"
+
+@A = common global i16* null, align 8
+
+define void @f() {
+entry:
+ %a = load i16*, i16** @A, align 8
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %ind = phi i64 [ 0, %entry ], [ %add, %for.body ]
+
+ %arrayidxA = getelementptr inbounds i16, i16* %a, i64 %ind
+ %loadA = load i16, i16* %arrayidxA, align 2
+
+ %mul = mul i16 %loadA, 2
+
+ %next = add nuw nsw i64 %ind, 4
+ %arrayidxA_next = getelementptr inbounds i16, i16* %a, i64 %next
+ store i16 %mul, i16* %arrayidxA_next, align 2
+
+ %add = add nuw nsw i64 %ind, 1
+ %exitcond = icmp eq i64 %add, 20
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret void
+}
diff --git a/test/Analysis/LoopAccessAnalysis/store-to-invariant-check1.ll b/test/Analysis/LoopAccessAnalysis/store-to-invariant-check1.ll
index 8ab8ab2a55b6b..ac8803ea9ebca 100644
--- a/test/Analysis/LoopAccessAnalysis/store-to-invariant-check1.ll
+++ b/test/Analysis/LoopAccessAnalysis/store-to-invariant-check1.ll
@@ -1,4 +1,5 @@
-; RUN: opt < %s -loop-accesses -analyze | FileCheck %s
+; RUN: opt < %s -loop-accesses -analyze | FileCheck -check-prefix=OLDPM %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck -check-prefix=NEWPM %s
; Test to confirm LAA will find store to invariant address.
; Inner loop has a store to invariant address.
@@ -9,8 +10,17 @@
; }
; }
-; CHECK: Store to invariant address was found in loop.
-; CHECK-NOT: Store to invariant address was not found in loop.
+; The LAA with the new PM is a loop pass so we go from inner to outer loops.
+
+; OLDPM: for.cond1.preheader:
+; OLDPM: Store to invariant address was not found in loop.
+; OLDPM: for.body3:
+; OLDPM: Store to invariant address was found in loop.
+
+; NEWPM: for.body3:
+; NEWPM: Store to invariant address was found in loop.
+; NEWPM: for.cond1.preheader:
+; NEWPM: Store to invariant address was not found in loop.
define i32 @foo(i32* nocapture %var1, i32* nocapture readonly %var2, i32 %itr) #0 {
entry:
diff --git a/test/Analysis/LoopAccessAnalysis/store-to-invariant-check2.ll b/test/Analysis/LoopAccessAnalysis/store-to-invariant-check2.ll
index 4da0906894926..711c14ef7728d 100644
--- a/test/Analysis/LoopAccessAnalysis/store-to-invariant-check2.ll
+++ b/test/Analysis/LoopAccessAnalysis/store-to-invariant-check2.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -loop-accesses -analyze | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
; Test to confirm LAA will not find store to invariant address.
; Inner loop has no store to invariant address.
diff --git a/test/Analysis/LoopAccessAnalysis/store-to-invariant-check3.ll b/test/Analysis/LoopAccessAnalysis/store-to-invariant-check3.ll
index 18315a59dc3a7..85fea798071f0 100644
--- a/test/Analysis/LoopAccessAnalysis/store-to-invariant-check3.ll
+++ b/test/Analysis/LoopAccessAnalysis/store-to-invariant-check3.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -loop-accesses -analyze | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
; Test to confirm LAA will find store to invariant address.
; Inner loop has a store to invariant address.
diff --git a/test/Analysis/LoopAccessAnalysis/stride-access-dependence.ll b/test/Analysis/LoopAccessAnalysis/stride-access-dependence.ll
index 5fc353e70cf83..4fe6f9f704f71 100644
--- a/test/Analysis/LoopAccessAnalysis/stride-access-dependence.ll
+++ b/test/Analysis/LoopAccessAnalysis/stride-access-dependence.ll
@@ -1,4 +1,5 @@
; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
@@ -384,7 +385,7 @@ for.body: ; preds = %entry, %for.body
; return sum;
; }
-; CHECK: for function 'vectorizable_unscaled_Write_Read':
+; CHECK: function 'vectorizable_unscaled_Write_Read':
; CHECK-NEXT: for.body:
; CHECK-NEXT: Memory dependences are safe
; CHECK-NEXT: Dependences:
diff --git a/test/Analysis/LoopAccessAnalysis/underlying-objects-1.ll b/test/Analysis/LoopAccessAnalysis/underlying-objects-1.ll
index 44820ed372221..705453b65cc50 100644
--- a/test/Analysis/LoopAccessAnalysis/underlying-objects-1.ll
+++ b/test/Analysis/LoopAccessAnalysis/underlying-objects-1.ll
@@ -1,4 +1,5 @@
; RUN: opt -basicaa -loop-accesses -analyze < %s | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
; In:
;
diff --git a/test/Analysis/LoopAccessAnalysis/underlying-objects-2.ll b/test/Analysis/LoopAccessAnalysis/underlying-objects-2.ll
index d388151365f18..f9d88e891be9b 100644
--- a/test/Analysis/LoopAccessAnalysis/underlying-objects-2.ll
+++ b/test/Analysis/LoopAccessAnalysis/underlying-objects-2.ll
@@ -1,4 +1,5 @@
; RUN: opt -basicaa -loop-accesses -analyze < %s | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
; This loop:
;
diff --git a/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks.ll b/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks.ll
index 7157b954c5b6d..7fbed6fcc15cf 100644
--- a/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks.ll
+++ b/test/Analysis/LoopAccessAnalysis/unsafe-and-rt-checks.ll
@@ -1,4 +1,5 @@
; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
+; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
; Analyze this loop:
; for (i = 0; i < n; i++)
diff --git a/test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll b/test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll
new file mode 100644
index 0000000000000..75a71b444283f
--- /dev/null
+++ b/test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll
@@ -0,0 +1,429 @@
+; RUN: opt -basicaa -loop-accesses -analyze < %s | FileCheck %s -check-prefix=LAA
+; RUN: opt -passes='require<aa>,require<scalar-evolution>,require<aa>,loop(print-access-info)' -aa-pipeline='basic-aa' -disable-output < %s 2>&1 | FileCheck %s --check-prefix=LAA
+; RUN: opt -loop-versioning -S < %s | FileCheck %s -check-prefix=LV
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+
+; For this loop:
+; unsigned index = 0;
+; for (int i = 0; i < n; i++) {
+; A[2 * index] = A[2 * index] + B[i];
+; index++;
+; }
+;
+; SCEV is unable to prove that A[2 * i] does not overflow.
+;
+; Analyzing the IR does not help us because the GEPs are not
+; affine AddRecExprs. However, we can turn them into AddRecExprs
+; using SCEV Predicates.
+;
+; Once we have an affine expression we need to add an additional NUSW
+; to check that the pointers don't wrap since the GEPs are not
+; inbound.
+
+; LAA-LABEL: f1
+; LAA: Memory dependences are safe{{$}}
+; LAA: SCEV assumptions:
+; LAA-NEXT: {0,+,2}<%for.body> Added Flags: <nusw>
+; LAA-NEXT: {%a,+,4}<%for.body> Added Flags: <nusw>
+
+; The expression for %mul_ext as analyzed by SCEV is
+; (zext i32 {0,+,2}<%for.body> to i64)
+; We have added the nusw flag to turn this expression into the SCEV expression:
+; i64 {0,+,2}<%for.body>
+
+; LAA: [PSE] %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext:
+; LAA-NEXT: ((2 * (zext i32 {0,+,2}<%for.body> to i64)) + %a)
+; LAA-NEXT: --> {%a,+,4}<%for.body>
+
+
+; LV-LABEL: f1
+; LV-LABEL: for.body.lver.check
+
+; LV: [[BETrunc:%[^ ]*]] = trunc i64 [[BE:%[^ ]*]] to i32
+; LV-NEXT: [[OFMul:%[^ ]*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 2, i32 [[BETrunc]])
+; LV-NEXT: [[OFMulResult:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 0
+; LV-NEXT: [[OFMulOverflow:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 1
+; LV-NEXT: [[AddEnd:%[^ ]*]] = add i32 0, [[OFMulResult]]
+; LV-NEXT: [[SubEnd:%[^ ]*]] = sub i32 0, [[OFMulResult]]
+; LV-NEXT: [[CmpNeg:%[^ ]*]] = icmp ugt i32 [[SubEnd]], 0
+; LV-NEXT: [[CmpPos:%[^ ]*]] = icmp ult i32 [[AddEnd]], 0
+; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 false, i1 [[CmpNeg]], i1 [[CmpPos]]
+; LV-NEXT: [[BECheck:%[^ ]*]] = icmp ugt i64 [[BE]], 4294967295
+; LV-NEXT: [[CheckOr0:%[^ ]*]] = or i1 [[Cmp]], [[BECheck]]
+; LV-NEXT: [[PredCheck0:%[^ ]*]] = or i1 [[CheckOr0]], [[OFMulOverflow]]
+
+; LV-NEXT: [[Or0:%[^ ]*]] = or i1 false, [[PredCheck0]]
+
+; LV-NEXT: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE]])
+; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0
+; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1
+; LV-NEXT: [[AddEnd1:%[^ ]*]] = add i64 %a2, [[OFMulResult1]]
+; LV-NEXT: [[SubEnd1:%[^ ]*]] = sub i64 %a2, [[OFMulResult1]]
+; LV-NEXT: [[CmpNeg1:%[^ ]*]] = icmp ugt i64 [[SubEnd1]], %a2
+; LV-NEXT: [[CmpPos1:%[^ ]*]] = icmp ult i64 [[AddEnd1]], %a2
+; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 false, i1 [[CmpNeg1]], i1 [[CmpPos1]]
+; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]]
+
+; LV: [[FinalCheck:%[^ ]*]] = or i1 [[Or0]], [[PredCheck1]]
+; LV: br i1 [[FinalCheck]], label %for.body.ph.lver.orig, label %for.body.ph
+define void @f1(i16* noalias %a,
+ i16* noalias %b, i64 %N) {
+entry:
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %ind = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+ %ind1 = phi i32 [ 0, %entry ], [ %inc1, %for.body ]
+
+ %mul = mul i32 %ind1, 2
+ %mul_ext = zext i32 %mul to i64
+
+ %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext
+ %loadA = load i16, i16* %arrayidxA, align 2
+
+ %arrayidxB = getelementptr i16, i16* %b, i64 %ind
+ %loadB = load i16, i16* %arrayidxB, align 2
+
+ %add = mul i16 %loadA, %loadB
+
+ store i16 %add, i16* %arrayidxA, align 2
+
+ %inc = add nuw nsw i64 %ind, 1
+ %inc1 = add i32 %ind1, 1
+
+ %exitcond = icmp eq i64 %inc, %N
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret void
+}
+
+; For this loop:
+; unsigned index = n;
+; for (int i = 0; i < n; i++) {
+; A[2 * index] = A[2 * index] + B[i];
+; index--;
+; }
+;
+; the SCEV expression for 2 * index is not an AddRecExpr
+; (and implictly not affine). However, we are able to make assumptions
+; that will turn the expression into an affine one and continue the
+; analysis.
+;
+; Once we have an affine expression we need to add an additional NUSW
+; to check that the pointers don't wrap since the GEPs are not
+; inbounds.
+;
+; This loop has a negative stride for A, and the nusw flag is required in
+; order to properly extend the increment from i32 -4 to i64 -4.
+
+; LAA-LABEL: f2
+; LAA: Memory dependences are safe{{$}}
+; LAA: SCEV assumptions:
+; LAA-NEXT: {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> Added Flags: <nusw>
+; LAA-NEXT: {((2 * (zext i32 (2 * (trunc i64 %N to i32)) to i64)) + %a),+,-4}<%for.body> Added Flags: <nusw>
+
+; The expression for %mul_ext as analyzed by SCEV is
+; (zext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64)
+; We have added the nusw flag to turn this expression into the following SCEV:
+; i64 {zext i32 (2 * (trunc i64 %N to i32)) to i64,+,-2}<%for.body>
+
+; LAA: [PSE] %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext:
+; LAA-NEXT: ((2 * (zext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64)) + %a)
+; LAA-NEXT: --> {((2 * (zext i32 (2 * (trunc i64 %N to i32)) to i64)) + %a),+,-4}<%for.body>
+
+; LV-LABEL: f2
+; LV-LABEL: for.body.lver.check
+
+; LV: [[OFMul:%[^ ]*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 2, i32 [[BETrunc:%[^ ]*]])
+; LV-NEXT: [[OFMulResult:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 0
+; LV-NEXT: [[OFMulOverflow:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 1
+; LV-NEXT: [[AddEnd:%[^ ]*]] = add i32 [[Start:%[^ ]*]], [[OFMulResult]]
+; LV-NEXT: [[SubEnd:%[^ ]*]] = sub i32 [[Start]], [[OFMulResult]]
+; LV-NEXT: [[CmpNeg:%[^ ]*]] = icmp ugt i32 [[SubEnd]], [[Start]]
+; LV-NEXT: [[CmpPos:%[^ ]*]] = icmp ult i32 [[AddEnd]], [[Start]]
+; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 true, i1 [[CmpNeg]], i1 [[CmpPos]]
+; LV-NEXT: [[BECheck:%[^ ]*]] = icmp ugt i64 [[BE]], 4294967295
+; LV-NEXT: [[CheckOr0:%[^ ]*]] = or i1 [[Cmp]], [[BECheck]]
+; LV-NEXT: [[PredCheck0:%[^ ]*]] = or i1 [[CheckOr0]], [[OFMulOverflow]]
+
+; LV-NEXT: [[Or0:%[^ ]*]] = or i1 false, [[PredCheck0]]
+
+; LV: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE]])
+; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0
+; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1
+; LV-NEXT: [[AddEnd1:%[^ ]*]] = add i64 [[Start:%[^ ]*]], [[OFMulResult1]]
+; LV-NEXT: [[SubEnd1:%[^ ]*]] = sub i64 [[Start]], [[OFMulResult1]]
+; LV-NEXT: [[CmpNeg1:%[^ ]*]] = icmp ugt i64 [[SubEnd1]], [[Start]]
+; LV-NEXT: [[CmpPos1:%[^ ]*]] = icmp ult i64 [[AddEnd1]], [[Start]]
+; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 true, i1 [[CmpNeg1]], i1 [[CmpPos1]]
+; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]]
+
+; LV: [[FinalCheck:%[^ ]*]] = or i1 [[Or0]], [[PredCheck1]]
+; LV: br i1 [[FinalCheck]], label %for.body.ph.lver.orig, label %for.body.ph
+define void @f2(i16* noalias %a,
+ i16* noalias %b, i64 %N) {
+entry:
+ %TruncN = trunc i64 %N to i32
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %ind = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+ %ind1 = phi i32 [ %TruncN, %entry ], [ %dec, %for.body ]
+
+ %mul = mul i32 %ind1, 2
+ %mul_ext = zext i32 %mul to i64
+
+ %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext
+ %loadA = load i16, i16* %arrayidxA, align 2
+
+ %arrayidxB = getelementptr i16, i16* %b, i64 %ind
+ %loadB = load i16, i16* %arrayidxB, align 2
+
+ %add = mul i16 %loadA, %loadB
+
+ store i16 %add, i16* %arrayidxA, align 2
+
+ %inc = add nuw nsw i64 %ind, 1
+ %dec = sub i32 %ind1, 1
+
+ %exitcond = icmp eq i64 %inc, %N
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret void
+}
+
+; We replicate the tests above, but this time sign extend 2 * index instead
+; of zero extending it.
+
+; LAA-LABEL: f3
+; LAA: Memory dependences are safe{{$}}
+; LAA: SCEV assumptions:
+; LAA-NEXT: {0,+,2}<%for.body> Added Flags: <nssw>
+; LAA-NEXT: {%a,+,4}<%for.body> Added Flags: <nusw>
+
+; The expression for %mul_ext as analyzed by SCEV is
+; i64 (sext i32 {0,+,2}<%for.body> to i64)
+; We have added the nssw flag to turn this expression into the following SCEV:
+; i64 {0,+,2}<%for.body>
+
+; LAA: [PSE] %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext:
+; LAA-NEXT: ((2 * (sext i32 {0,+,2}<%for.body> to i64)) + %a)
+; LAA-NEXT: --> {%a,+,4}<%for.body>
+
+; LV-LABEL: f3
+; LV-LABEL: for.body.lver.check
+
+; LV: [[OFMul:%[^ ]*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 2, i32 [[BETrunc:%[^ ]*]])
+; LV-NEXT: [[OFMulResult:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 0
+; LV-NEXT: [[OFMulOverflow:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 1
+; LV-NEXT: [[AddEnd:%[^ ]*]] = add i32 0, [[OFMulResult]]
+; LV-NEXT: [[SubEnd:%[^ ]*]] = sub i32 0, [[OFMulResult]]
+; LV-NEXT: [[CmpNeg:%[^ ]*]] = icmp sgt i32 [[SubEnd]], 0
+; LV-NEXT: [[CmpPos:%[^ ]*]] = icmp slt i32 [[AddEnd]], 0
+; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 false, i1 [[CmpNeg]], i1 [[CmpPos]]
+; LV-NEXT: [[BECheck:%[^ ]*]] = icmp ugt i64 [[BE]], 4294967295
+; LV-NEXT: [[CheckOr0:%[^ ]*]] = or i1 [[Cmp]], [[BECheck]]
+; LV-NEXT: [[PredCheck0:%[^ ]*]] = or i1 [[CheckOr0]], [[OFMulOverflow]]
+
+; LV-NEXT: [[Or0:%[^ ]*]] = or i1 false, [[PredCheck0]]
+
+; LV: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE:%[^ ]*]])
+; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0
+; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1
+; LV-NEXT: [[AddEnd1:%[^ ]*]] = add i64 %a2, [[OFMulResult1]]
+; LV-NEXT: [[SubEnd1:%[^ ]*]] = sub i64 %a2, [[OFMulResult1]]
+; LV-NEXT: [[CmpNeg1:%[^ ]*]] = icmp ugt i64 [[SubEnd1]], %a2
+; LV-NEXT: [[CmpPos1:%[^ ]*]] = icmp ult i64 [[AddEnd1]], %a2
+; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 false, i1 [[CmpNeg1]], i1 [[CmpPos1]]
+; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]]
+
+; LV: [[FinalCheck:%[^ ]*]] = or i1 [[Or0]], [[PredCheck1]]
+; LV: br i1 [[FinalCheck]], label %for.body.ph.lver.orig, label %for.body.ph
+define void @f3(i16* noalias %a,
+ i16* noalias %b, i64 %N) {
+entry:
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %ind = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+ %ind1 = phi i32 [ 0, %entry ], [ %inc1, %for.body ]
+
+ %mul = mul i32 %ind1, 2
+ %mul_ext = sext i32 %mul to i64
+
+ %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext
+ %loadA = load i16, i16* %arrayidxA, align 2
+
+ %arrayidxB = getelementptr i16, i16* %b, i64 %ind
+ %loadB = load i16, i16* %arrayidxB, align 2
+
+ %add = mul i16 %loadA, %loadB
+
+ store i16 %add, i16* %arrayidxA, align 2
+
+ %inc = add nuw nsw i64 %ind, 1
+ %inc1 = add i32 %ind1, 1
+
+ %exitcond = icmp eq i64 %inc, %N
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret void
+}
+
+; LAA-LABEL: f4
+; LAA: Memory dependences are safe{{$}}
+; LAA: SCEV assumptions:
+; LAA-NEXT: {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> Added Flags: <nssw>
+; LAA-NEXT: {((2 * (sext i32 (2 * (trunc i64 %N to i32)) to i64)) + %a),+,-4}<%for.body> Added Flags: <nusw>
+
+; The expression for %mul_ext as analyzed by SCEV is
+; i64 (sext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64)
+; We have added the nssw flag to turn this expression into the following SCEV:
+; i64 {sext i32 (2 * (trunc i64 %N to i32)) to i64,+,-2}<%for.body>
+
+; LAA: [PSE] %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext:
+; LAA-NEXT: ((2 * (sext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64)) + %a)
+; LAA-NEXT: --> {((2 * (sext i32 (2 * (trunc i64 %N to i32)) to i64)) + %a),+,-4}<%for.body>
+
+; LV-LABEL: f4
+; LV-LABEL: for.body.lver.check
+
+; LV: [[OFMul:%[^ ]*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 2, i32 [[BETrunc:%[^ ]*]])
+; LV-NEXT: [[OFMulResult:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 0
+; LV-NEXT: [[OFMulOverflow:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 1
+; LV-NEXT: [[AddEnd:%[^ ]*]] = add i32 [[Start:%[^ ]*]], [[OFMulResult]]
+; LV-NEXT: [[SubEnd:%[^ ]*]] = sub i32 [[Start]], [[OFMulResult]]
+; LV-NEXT: [[CmpNeg:%[^ ]*]] = icmp sgt i32 [[SubEnd]], [[Start]]
+; LV-NEXT: [[CmpPos:%[^ ]*]] = icmp slt i32 [[AddEnd]], [[Start]]
+; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 true, i1 [[CmpNeg]], i1 [[CmpPos]]
+; LV-NEXT: [[BECheck:%[^ ]*]] = icmp ugt i64 [[BE]], 4294967295
+; LV-NEXT: [[CheckOr0:%[^ ]*]] = or i1 [[Cmp]], [[BECheck]]
+; LV-NEXT: [[PredCheck0:%[^ ]*]] = or i1 [[CheckOr0]], [[OFMulOverflow]]
+
+; LV-NEXT: [[Or0:%[^ ]*]] = or i1 false, [[PredCheck0]]
+
+; LV: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE:%[^ ]*]])
+; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0
+; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1
+; LV-NEXT: [[AddEnd1:%[^ ]*]] = add i64 [[Start:%[^ ]*]], [[OFMulResult1]]
+; LV-NEXT: [[SubEnd1:%[^ ]*]] = sub i64 [[Start]], [[OFMulResult1]]
+; LV-NEXT: [[CmpNeg1:%[^ ]*]] = icmp ugt i64 [[SubEnd1]], [[Start]]
+; LV-NEXT: [[CmpPos1:%[^ ]*]] = icmp ult i64 [[AddEnd1]], [[Start]]
+; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 true, i1 [[CmpNeg1]], i1 [[CmpPos1]]
+; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]]
+
+; LV: [[FinalCheck:%[^ ]*]] = or i1 [[Or0]], [[PredCheck1]]
+; LV: br i1 [[FinalCheck]], label %for.body.ph.lver.orig, label %for.body.ph
+define void @f4(i16* noalias %a,
+ i16* noalias %b, i64 %N) {
+entry:
+ %TruncN = trunc i64 %N to i32
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %ind = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+ %ind1 = phi i32 [ %TruncN, %entry ], [ %dec, %for.body ]
+
+ %mul = mul i32 %ind1, 2
+ %mul_ext = sext i32 %mul to i64
+
+ %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext
+ %loadA = load i16, i16* %arrayidxA, align 2
+
+ %arrayidxB = getelementptr i16, i16* %b, i64 %ind
+ %loadB = load i16, i16* %arrayidxB, align 2
+
+ %add = mul i16 %loadA, %loadB
+
+ store i16 %add, i16* %arrayidxA, align 2
+
+ %inc = add nuw nsw i64 %ind, 1
+ %dec = sub i32 %ind1, 1
+
+ %exitcond = icmp eq i64 %inc, %N
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret void
+}
+
+; The following function is similar to the one above, but has the GEP
+; to pointer %A inbounds. The index %mul doesn't have the nsw flag.
+; This means that the SCEV expression for %mul can wrap and we need
+; a SCEV predicate to continue analysis.
+;
+; We can still analyze this by adding the required no wrap SCEV predicates.
+
+; LAA-LABEL: f5
+; LAA: Memory dependences are safe{{$}}
+; LAA: SCEV assumptions:
+; LAA-NEXT: {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> Added Flags: <nssw>
+; LAA-NEXT: {((2 * (sext i32 (2 * (trunc i64 %N to i32)) to i64)) + %a),+,-4}<%for.body> Added Flags: <nusw>
+
+; LAA: [PSE] %arrayidxA = getelementptr inbounds i16, i16* %a, i32 %mul:
+; LAA-NEXT: ((2 * (sext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64))<nsw> + %a)<nsw>
+; LAA-NEXT: --> {((2 * (sext i32 (2 * (trunc i64 %N to i32)) to i64)) + %a),+,-4}<%for.body>
+
+; LV-LABEL: f5
+; LV-LABEL: for.body.lver.check
+; LV: [[OFMul:%[^ ]*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 2, i32 [[BETrunc:%[^ ]*]])
+; LV-NEXT: [[OFMulResult:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 0
+; LV-NEXT: [[OFMulOverflow:%[^ ]*]] = extractvalue { i32, i1 } [[OFMul]], 1
+; LV-NEXT: [[AddEnd:%[^ ]*]] = add i32 [[Start:%[^ ]*]], [[OFMulResult]]
+; LV-NEXT: [[SubEnd:%[^ ]*]] = sub i32 [[Start]], [[OFMulResult]]
+; LV-NEXT: [[CmpNeg:%[^ ]*]] = icmp sgt i32 [[SubEnd]], [[Start]]
+; LV-NEXT: [[CmpPos:%[^ ]*]] = icmp slt i32 [[AddEnd]], [[Start]]
+; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 true, i1 [[CmpNeg]], i1 [[CmpPos]]
+; LV-NEXT: [[BECheck:%[^ ]*]] = icmp ugt i64 [[BE]], 4294967295
+; LV-NEXT: [[CheckOr0:%[^ ]*]] = or i1 [[Cmp]], [[BECheck]]
+; LV-NEXT: [[PredCheck0:%[^ ]*]] = or i1 [[CheckOr0]], [[OFMulOverflow]]
+
+; LV-NEXT: [[Or0:%[^ ]*]] = or i1 false, [[PredCheck0]]
+
+; LV: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE:%[^ ]*]])
+; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0
+; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1
+; LV-NEXT: [[AddEnd1:%[^ ]*]] = add i64 [[Start:%[^ ]*]], [[OFMulResult1]]
+; LV-NEXT: [[SubEnd1:%[^ ]*]] = sub i64 [[Start]], [[OFMulResult1]]
+; LV-NEXT: [[CmpNeg1:%[^ ]*]] = icmp ugt i64 [[SubEnd1]], [[Start]]
+; LV-NEXT: [[CmpPos1:%[^ ]*]] = icmp ult i64 [[AddEnd1]], [[Start]]
+; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 true, i1 [[CmpNeg1]], i1 [[CmpPos1]]
+; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]]
+
+; LV: [[FinalCheck:%[^ ]*]] = or i1 [[Or0]], [[PredCheck1]]
+; LV: br i1 [[FinalCheck]], label %for.body.ph.lver.orig, label %for.body.ph
+define void @f5(i16* noalias %a,
+ i16* noalias %b, i64 %N) {
+entry:
+ %TruncN = trunc i64 %N to i32
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %ind = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+ %ind1 = phi i32 [ %TruncN, %entry ], [ %dec, %for.body ]
+
+ %mul = mul i32 %ind1, 2
+
+ %arrayidxA = getelementptr inbounds i16, i16* %a, i32 %mul
+ %loadA = load i16, i16* %arrayidxA, align 2
+
+ %arrayidxB = getelementptr inbounds i16, i16* %b, i64 %ind
+ %loadB = load i16, i16* %arrayidxB, align 2
+
+ %add = mul i16 %loadA, %loadB
+
+ store i16 %add, i16* %arrayidxA, align 2
+
+ %inc = add nuw nsw i64 %ind, 1
+ %dec = sub i32 %ind1, 1
+
+ %exitcond = icmp eq i64 %inc, %N
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret void
+}
diff --git a/test/Analysis/PostDominators/pr1098.ll b/test/Analysis/PostDominators/pr1098.ll
index 2eed21371276e..1dae0c566f055 100644
--- a/test/Analysis/PostDominators/pr1098.ll
+++ b/test/Analysis/PostDominators/pr1098.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -postdomtree -analyze | FileCheck %s
+; RUN: opt < %s -passes='print<postdomtree>' 2>&1 | FileCheck %s
; PR932
define void @foo(i1 %x) {
diff --git a/test/Analysis/ProfileSummary/basic.ll b/test/Analysis/ProfileSummary/basic.ll
new file mode 100644
index 0000000000000..e417e459f04ca
--- /dev/null
+++ b/test/Analysis/ProfileSummary/basic.ll
@@ -0,0 +1,39 @@
+; RUN: opt < %s -disable-output -passes=print-profile-summary -S 2>&1 | FileCheck %s
+
+define void @f1() !prof !20 {
+; CHECK-LABEL: f1 :hot
+
+ ret void
+}
+
+define void @f2() !prof !21 {
+; CHECK-LABEL: f2 :cold
+
+ ret void
+}
+
+define void @f3() !prof !22 {
+; CHECK-LABEL: f3
+
+ ret void
+}
+
+!llvm.module.flags = !{!1}
+!20 = !{!"function_entry_count", i64 400}
+!21 = !{!"function_entry_count", i64 1}
+!22 = !{!"function_entry_count", i64 100}
+
+!1 = !{i32 1, !"ProfileSummary", !2}
+!2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
+!3 = !{!"ProfileFormat", !"InstrProf"}
+!4 = !{!"TotalCount", i64 10000}
+!5 = !{!"MaxCount", i64 10}
+!6 = !{!"MaxInternalCount", i64 1}
+!7 = !{!"MaxFunctionCount", i64 1000}
+!8 = !{!"NumCounts", i64 3}
+!9 = !{!"NumFunctions", i64 3}
+!10 = !{!"DetailedSummary", !11}
+!11 = !{!12, !13, !14}
+!12 = !{i32 10000, i64 100, i32 1}
+!13 = !{i32 999000, i64 100, i32 1}
+!14 = !{i32 999999, i64 1, i32 2}
diff --git a/test/Analysis/RegionInfo/20100809_bb_not_in_domtree.ll b/test/Analysis/RegionInfo/20100809_bb_not_in_domtree.ll
index 0dfa0bf9cd8d7..84e72783dcde4 100644
--- a/test/Analysis/RegionInfo/20100809_bb_not_in_domtree.ll
+++ b/test/Analysis/RegionInfo/20100809_bb_not_in_domtree.ll
@@ -1,4 +1,6 @@
; RUN: opt -regions < %s
+; RUN: opt < %s -passes='print<regions>'
+
define i32 @main() nounwind {
entry:
br label %for.cond
diff --git a/test/Analysis/RegionInfo/block_sort.ll b/test/Analysis/RegionInfo/block_sort.ll
index d7ef79cf6b557..ce1a48132901e 100644
--- a/test/Analysis/RegionInfo/block_sort.ll
+++ b/test/Analysis/RegionInfo/block_sort.ll
@@ -4,6 +4,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define void @BZ2_blockSort() nounwind {
start:
br label %while
diff --git a/test/Analysis/RegionInfo/cond_loop.ll b/test/Analysis/RegionInfo/cond_loop.ll
index 0da4e5dca3d39..333cdffacd107 100644
--- a/test/Analysis/RegionInfo/cond_loop.ll
+++ b/test/Analysis/RegionInfo/cond_loop.ll
@@ -4,6 +4,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define void @normal_condition() nounwind {
5:
br label %"0"
diff --git a/test/Analysis/RegionInfo/condition_complicated.ll b/test/Analysis/RegionInfo/condition_complicated.ll
index 53f13c10eaf39..ba107bfd5dee5 100644
--- a/test/Analysis/RegionInfo/condition_complicated.ll
+++ b/test/Analysis/RegionInfo/condition_complicated.ll
@@ -4,6 +4,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define internal fastcc zeroext i8 @handle_compress() nounwind {
end165:
br i1 1, label %false239, label %true181
diff --git a/test/Analysis/RegionInfo/condition_complicated_2.ll b/test/Analysis/RegionInfo/condition_complicated_2.ll
index fd04afc20dcad..90717712489a6 100644
--- a/test/Analysis/RegionInfo/condition_complicated_2.ll
+++ b/test/Analysis/RegionInfo/condition_complicated_2.ll
@@ -4,6 +4,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define internal fastcc void @compress() nounwind {
end33:
br i1 1, label %end124, label %lor.lhs.false95
diff --git a/test/Analysis/RegionInfo/condition_forward_edge.ll b/test/Analysis/RegionInfo/condition_forward_edge.ll
index 88c45c2e6efd3..9c1ac752bc6ba 100644
--- a/test/Analysis/RegionInfo/condition_forward_edge.ll
+++ b/test/Analysis/RegionInfo/condition_forward_edge.ll
@@ -4,6 +4,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define void @normal_condition() nounwind {
0:
br label %"1"
diff --git a/test/Analysis/RegionInfo/condition_same_exit.ll b/test/Analysis/RegionInfo/condition_same_exit.ll
index bfb0df84b44de..570c772ea741c 100644
--- a/test/Analysis/RegionInfo/condition_same_exit.ll
+++ b/test/Analysis/RegionInfo/condition_same_exit.ll
@@ -4,6 +4,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define void @normal_condition() nounwind {
0:
br i1 1, label %"1", label %"4"
diff --git a/test/Analysis/RegionInfo/condition_simple.ll b/test/Analysis/RegionInfo/condition_simple.ll
index 3f93a6ecd3589..46c1b940a517d 100644
--- a/test/Analysis/RegionInfo/condition_simple.ll
+++ b/test/Analysis/RegionInfo/condition_simple.ll
@@ -4,6 +4,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define void @normal_condition() nounwind {
0:
br label %"1"
diff --git a/test/Analysis/RegionInfo/exit_in_condition.ll b/test/Analysis/RegionInfo/exit_in_condition.ll
index ac409ec1bb25c..4eb3be4b6be08 100644
--- a/test/Analysis/RegionInfo/exit_in_condition.ll
+++ b/test/Analysis/RegionInfo/exit_in_condition.ll
@@ -4,6 +4,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define internal fastcc zeroext i8 @handle_compress() nounwind {
entry:
br label %outer
diff --git a/test/Analysis/RegionInfo/loop_with_condition.ll b/test/Analysis/RegionInfo/loop_with_condition.ll
index 4c1c8654ca4ff..4122b20029499 100644
--- a/test/Analysis/RegionInfo/loop_with_condition.ll
+++ b/test/Analysis/RegionInfo/loop_with_condition.ll
@@ -5,6 +5,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define void @normal_condition() nounwind {
0:
br label %"1"
diff --git a/test/Analysis/RegionInfo/loops_1.ll b/test/Analysis/RegionInfo/loops_1.ll
index 9efe619ad9d7f..aedb4842f99c3 100644
--- a/test/Analysis/RegionInfo/loops_1.ll
+++ b/test/Analysis/RegionInfo/loops_1.ll
@@ -4,6 +4,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define internal fastcc zeroext i8 @loops_1() nounwind {
entry:
br i1 1, label %outer , label %a
diff --git a/test/Analysis/RegionInfo/loops_2.ll b/test/Analysis/RegionInfo/loops_2.ll
index ca7eca75affd2..3ac83b01d43e1 100644
--- a/test/Analysis/RegionInfo/loops_2.ll
+++ b/test/Analysis/RegionInfo/loops_2.ll
@@ -4,6 +4,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define void @meread_() nounwind {
entry:
br label %bb23
diff --git a/test/Analysis/RegionInfo/mix_1.ll b/test/Analysis/RegionInfo/mix_1.ll
index 55001c7f435c2..3ae22af9e3d0a 100644
--- a/test/Analysis/RegionInfo/mix_1.ll
+++ b/test/Analysis/RegionInfo/mix_1.ll
@@ -5,6 +5,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define void @a_linear_impl_fig_1() nounwind {
0:
diff --git a/test/Analysis/RegionInfo/nested_loops.ll b/test/Analysis/RegionInfo/nested_loops.ll
index 3e73b3a328f63..6db32376fd7ef 100644
--- a/test/Analysis/RegionInfo/nested_loops.ll
+++ b/test/Analysis/RegionInfo/nested_loops.ll
@@ -5,6 +5,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define internal fastcc zeroext i8 @handle_compress() nounwind {
entry:
br label %outer
diff --git a/test/Analysis/RegionInfo/next.ll b/test/Analysis/RegionInfo/next.ll
index b22bbcc2b6d5c..617273f759739 100644
--- a/test/Analysis/RegionInfo/next.ll
+++ b/test/Analysis/RegionInfo/next.ll
@@ -4,6 +4,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define void @MAIN__() nounwind {
entry:
br label %__label_002001.outer
diff --git a/test/Analysis/RegionInfo/paper.ll b/test/Analysis/RegionInfo/paper.ll
index 0398d2baa2256..3e592f4f9e931 100644
--- a/test/Analysis/RegionInfo/paper.ll
+++ b/test/Analysis/RegionInfo/paper.ll
@@ -4,6 +4,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define void @a_linear_impl_fig_1() nounwind {
0:
br label %"1"
diff --git a/test/Analysis/RegionInfo/two_loops_same_header.ll b/test/Analysis/RegionInfo/two_loops_same_header.ll
index 25713420a3b7a..2d5fa080c3b6b 100644
--- a/test/Analysis/RegionInfo/two_loops_same_header.ll
+++ b/test/Analysis/RegionInfo/two_loops_same_header.ll
@@ -4,6 +4,8 @@
; RUN: opt -regions -print-region-style=bb -analyze < %s 2>&1 | FileCheck -check-prefix=BBIT %s
; RUN: opt -regions -print-region-style=rn -analyze < %s 2>&1 | FileCheck -check-prefix=RNIT %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
+
define internal fastcc zeroext i8 @handle_compress() nounwind {
entry:
br label %outer
diff --git a/test/Analysis/RegionInfo/unreachable_bb.ll b/test/Analysis/RegionInfo/unreachable_bb.ll
index 626ccbe304c30..5dd1be958e71a 100644
--- a/test/Analysis/RegionInfo/unreachable_bb.ll
+++ b/test/Analysis/RegionInfo/unreachable_bb.ll
@@ -1,4 +1,5 @@
; RUN: opt -regions -analyze < %s | FileCheck %s
+; RUN: opt < %s -passes='print<regions>' 2>&1 | FileCheck %s
; We should not crash if there are some bbs that are not reachable.
define void @f() {
diff --git a/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll b/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll
new file mode 100644
index 0000000000000..16d9cc5443872
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll
@@ -0,0 +1,26 @@
+; RUN: opt -analyze -scalar-evolution < %s | 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 @f_0() {
+; CHECK-LABEL: Printing analysis 'Scalar Evolution Analysis' for function 'f_0':
+; CHECK: Loop %for.body: backedge-taken count is 5
+; CHECK: Loop %for.body: max backedge-taken count is 5
+; CHECK: Loop %for.body: Predicated backedge-taken count is 5
+
+entry:
+ br label %for.body
+
+for.body:
+ %i.05 = phi i32 [ 32, %entry ], [ %div4, %for.body ]
+ tail call void @dummy()
+ %div4 = lshr i32 %i.05, 1
+ %cmp = icmp eq i32 %div4, 0
+ br i1 %cmp, label %for.cond.cleanup, label %for.body
+
+for.cond.cleanup:
+ ret void
+}
+
+declare void @dummy()
diff --git a/test/Analysis/ScalarEvolution/expander-replace-congruent-ivs.ll b/test/Analysis/ScalarEvolution/expander-replace-congruent-ivs.ll
new file mode 100644
index 0000000000000..0adb92d671b16
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/expander-replace-congruent-ivs.ll
@@ -0,0 +1,111 @@
+; RUN: opt -S -indvars < %s | FileCheck %s
+
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+; SCEVExpander would try to RAUW %val_2 with %c.lcssa, breaking "def
+; dominates uses".
+
+define void @pr27232(i32 %val) {
+; CHECK-LABEL: @pr27232(
+entry:
+ br i1 undef, label %loop_0.cond, label %for.body.us
+
+for.body.us:
+ br label %loop_0.cond
+
+loop_0.cond:
+ %val_2 = phi i32 [ %val, %for.body.us ], [ undef, %entry ]
+ br i1 true, label %loop_0.ph, label %loop_1.ph
+
+loop_0.ph:
+ br label %loop_0
+
+loop_1.exit:
+ br label %loop_1.ph
+
+loop_1.ph:
+ %c.lcssa = phi i32 [ 0, %loop_0.cond ], [ %val_2, %loop_1.exit ]
+ br label %loop_1
+
+loop_0:
+ br i1 undef, label %loop_0, label %loop_1.exit
+
+loop_1:
+ %d.1 = phi i32 [ %c.lcssa, %loop_1 ], [ %val_2, %loop_1.ph ]
+ %t.1 = phi i32 [ %val_2, %loop_1 ], [ %c.lcssa, %loop_1.ph ]
+ br i1 undef, label %leave, label %loop_1
+
+leave:
+ ret void
+}
+
+
+; @ReplaceArg_0 and @ReplaceArg_1 used to trigger a failed cast<>
+; assertion in SCEVExpander.
+
+define void @ReplaceArg_0(i32 %val) {
+; CHECK-LABEL: @ReplaceArg_0(
+entry:
+ br i1 undef, label %loop_0.cond, label %for.body.us
+
+for.body.us:
+ br label %loop_0.cond
+
+loop_0.cond:
+ br i1 true, label %loop_0.ph, label %loop_1.ph
+
+loop_0.ph:
+ br label %loop_0
+
+loop_1.exit:
+ br label %loop_1.ph
+
+loop_1.ph:
+ %c.lcssa = phi i32 [ 0, %loop_0.cond ], [ %val, %loop_1.exit ]
+ br label %loop_1
+
+loop_0:
+ br i1 undef, label %loop_0, label %loop_1.exit
+
+loop_1:
+ %d.1 = phi i32 [ %c.lcssa, %loop_1 ], [ %val, %loop_1.ph ]
+ %t.1 = phi i32 [ %val, %loop_1 ], [ %c.lcssa, %loop_1.ph ]
+ br i1 undef, label %leave, label %loop_1
+
+leave:
+ ret void
+}
+
+define void @ReplaceArg_1(i32 %val) {
+; CHECK-LABEL: @ReplaceArg_1(
+entry:
+ br i1 undef, label %loop_0.cond, label %for.body.us
+
+for.body.us:
+ br label %loop_0.cond
+
+loop_0.cond:
+ br i1 true, label %loop_0.ph, label %loop_1.ph
+
+loop_0.ph:
+ br label %loop_0
+
+loop_1.exit:
+ br label %loop_1.ph
+
+loop_1.ph:
+ %c.lcssa = phi i32 [ 0, %loop_0.cond ], [ %val, %loop_1.exit ]
+ br label %loop_1
+
+loop_0:
+ br i1 undef, label %loop_0, label %loop_1.exit
+
+loop_1:
+ %t.1 = phi i32 [ %val, %loop_1 ], [ %c.lcssa, %loop_1.ph ]
+ %d.1 = phi i32 [ %c.lcssa, %loop_1 ], [ %val, %loop_1.ph ]
+ br i1 undef, label %leave, label %loop_1
+
+leave:
+ ret void
+}
diff --git a/test/Analysis/ScalarEvolution/flags-from-poison-dbg.ll b/test/Analysis/ScalarEvolution/flags-from-poison-dbg.ll
new file mode 100644
index 0000000000000..30b83578137af
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/flags-from-poison-dbg.ll
@@ -0,0 +1,75 @@
+; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s
+
+; Make sure poison value tracking works in the presence of @llvm.dbg
+; intrinsics. Unfortunately, I was not able to reduce this file
+; further while still keeping the debug info well formed.
+
+define void @foo(i32 %n, i32* %arr) !dbg !7 {
+; CHECK-LABEL: Classifying expressions for: @foo
+entry:
+ %cmp1 = icmp slt i32 0, %n, !dbg !12
+ br i1 %cmp1, label %for.body.lr.ph, label %for.end, !dbg !15
+
+for.body.lr.ph: ; preds = %entry
+ br label %for.body, !dbg !15
+
+for.body: ; preds = %for.inc, %for.body.lr.ph
+ %i.02 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]
+ %add = add nsw i32 %i.02, 50, !dbg !16
+ call void @llvm.dbg.value(metadata i32 %add, i64 0, metadata !18, metadata !19), !dbg !20
+ %idxprom = sext i32 %add to i64, !dbg !21
+
+; CHECK: %idxprom = sext i32 %add to i64
+; CHECK-NEXT: --> {50,+,1}<nuw><nsw><%for.body>
+
+ %arrayidx = getelementptr inbounds i32, i32* %arr, i64 %idxprom, !dbg !21
+ store i32 100, i32* %arrayidx, align 4, !dbg !22
+ br label %for.inc, !dbg !23
+
+for.inc: ; preds = %for.body
+ %inc = add nsw i32 %i.02, 1, !dbg !24
+ %cmp = icmp slt i32 %inc, %n, !dbg !12
+ br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge, !dbg !15, !llvm.loop !25
+
+for.cond.for.end_crit_edge: ; preds = %for.inc
+ br label %for.end, !dbg !15
+
+for.end: ; preds = %for.cond.for.end_crit_edge, %entry
+ ret void, !dbg !27
+}
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.value(metadata, i64, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 (llvm/trunk 271857)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "x.c", directory: "/Users/sanjoy/Code/clang/build/debug+asserts-x86")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 2}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"PIC Level", i32 2}
+!6 = !{!"clang version 3.9.0 (llvm/trunk 271857)"}
+!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
+!8 = !DISubroutineType(types: !9)
+!9 = !{null, !10, !11}
+!10 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64, align: 64)
+!12 = !DILocation(line: 2, column: 24, scope: !13)
+!13 = distinct !DILexicalBlock(scope: !14, file: !1, line: 2, column: 6)
+!14 = distinct !DILexicalBlock(scope: !7, file: !1, line: 2, column: 6)
+!15 = !DILocation(line: 2, column: 6, scope: !14)
+!16 = !DILocation(line: 3, column: 14, scope: !17)
+!17 = distinct !DILexicalBlock(scope: !13, file: !1, line: 2, column: 34)
+!18 = !DILocalVariable(name: "k", scope: !17, file: !1, line: 3, type: !10)
+!19 = !DIExpression()
+!20 = !DILocation(line: 3, column: 8, scope: !17)
+!21 = !DILocation(line: 4, column: 4, scope: !17)
+!22 = !DILocation(line: 4, column: 11, scope: !17)
+!23 = !DILocation(line: 5, column: 6, scope: !17)
+!24 = !DILocation(line: 2, column: 30, scope: !13)
+!25 = distinct !{!25, !26}
+!26 = !DILocation(line: 2, column: 6, scope: !7)
+!27 = !DILocation(line: 6, column: 1, scope: !7)
diff --git a/test/Analysis/ScalarEvolution/flags-from-poison.ll b/test/Analysis/ScalarEvolution/flags-from-poison.ll
index b1fe7f1138b6c..2fcb4c038f205 100644
--- a/test/Analysis/ScalarEvolution/flags-from-poison.ll
+++ b/test/Analysis/ScalarEvolution/flags-from-poison.ll
@@ -57,6 +57,30 @@ exit:
ret void
}
+define void @test-add-nuw-from-icmp(float* %input, i32 %offset,
+ i32 %numIterations) {
+; CHECK-LABEL: @test-add-nuw-from-icmp
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
+
+; CHECK: %index32 =
+; CHECK: --> {%offset,+,1}<nuw>
+ %index32 = add nuw i32 %i, %offset
+ %cmp = icmp sgt i32 %index32, 0
+ %cmp.idx = sext i1 %cmp to i32
+
+ %ptr = getelementptr inbounds float, float* %input, i32 %cmp.idx
+ %nexti = add nuw i32 %i, 1
+ %f = load float, float* %ptr, align 4
+ %exitcond = icmp eq i32 %nexti, %numIterations
+ br i1 %exitcond, label %exit, label %loop
+
+exit:
+ ret void
+}
+
; With no load to trigger UB from poison, we cannot infer nsw.
define void @test-add-no-load(float* %input, i32 %offset, i32 %numIterations) {
; CHECK-LABEL: @test-add-no-load
@@ -113,11 +137,65 @@ loop:
%i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]
; CHECK: %index32 =
+; CHECK: --> {%offset,+,1}<nsw>
+ %index32 = add nsw i32 %i, %offset
+
+ %ptr = getelementptr inbounds float, float* %input, i32 %index32
+ %nexti = add nsw i32 %i, 1
+ br label %loop2
+loop2:
+ %f = load float, float* %ptr, align 4
+ %exitcond = icmp eq i32 %nexti, %numIterations
+ br i1 %exitcond, label %exit, label %loop
+exit:
+ ret void
+}
+
+; Similar to test-add-not-header, but in this case the load
+; instruction may not be executed.
+define void @test-add-not-header3(float* %input, i32 %offset, i32 %numIterations,
+ i1* %cond_buf) {
+; CHECK-LABEL: @test-add-not-header3
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]
+
+; CHECK: %index32 =
; CHECK: --> {%offset,+,1}<nw>
%index32 = add nsw i32 %i, %offset
%ptr = getelementptr inbounds float, float* %input, i32 %index32
%nexti = add nsw i32 %i, 1
+ %cond = load volatile i1, i1* %cond_buf
+ br i1 %cond, label %loop2, label %exit
+loop2:
+ %f = load float, float* %ptr, align 4
+ %exitcond = icmp eq i32 %nexti, %numIterations
+ br i1 %exitcond, label %exit, label %loop
+exit:
+ ret void
+}
+
+; Same thing as test-add-not-header2, except we have a few extra
+; blocks.
+define void @test-add-not-header4(float* %input, i32 %offset, i32 %numIterations) {
+; CHECK-LABEL: @test-add-not-header4
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]
+
+; CHECK: %index32 =
+; CHECK: --> {%offset,+,1}<nsw>
+ %index32 = add nsw i32 %i, %offset
+
+ %ptr = getelementptr inbounds float, float* %input, i32 %index32
+ %nexti = add nsw i32 %i, 1
+ br label %loop3
+loop3:
+ br label %loop4
+loop4:
br label %loop2
loop2:
%f = load float, float* %ptr, align 4
@@ -127,6 +205,26 @@ exit:
ret void
}
+; Demonstrate why we need a Visited set in llvm::isKnownNotFullPoison.
+define void @test-add-not-header5(float* %input, i32 %offset) {
+; CHECK-LABEL: @test-add-not-header5
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
+
+; CHECK: %index32 =
+; CHECK: --> {%offset,+,1}<nw>
+ %index32 = add nsw i32 %i, %offset
+
+ %ptr = getelementptr inbounds float, float* %input, i32 %index32
+ %nexti = add nsw i32 %i, 1
+ br label %loop
+
+exit:
+ ret void
+}
+
; The call instruction makes it not guaranteed that the add will be
; executed, since it could run forever or throw an exception, so we
; cannot assume that the UB is realized.
@@ -346,7 +444,7 @@ loop:
%j = add nsw i32 %i, 1
; CHECK: %index32 =
-; CHECK: --> {(1 + %offset),+,1}<nsw>
+; CHECK: --> {(1 + %offset)<nsw>,+,1}<nsw>
%index32 = add nsw i32 %j, %offset
%ptr = getelementptr inbounds float, float* %input, i32 %index32
@@ -488,7 +586,7 @@ loop:
%i = phi i32 [ %nexti, %loop ], [ %start, %entry ]
; CHECK: %index32 =
-; CHECK: --> {((-1 * %halfsub)<nsw> + %start),+,1}<nsw>
+; CHECK: --> {((-1 * %halfsub)<nsw> + %start)<nsw>,+,1}<nsw>
%index32 = sub nsw i32 %i, %halfsub
%index64 = sext i32 %index32 to i64
@@ -547,7 +645,7 @@ loop:
%j = add nsw i32 %i, 1
; CHECK: %index32 =
-; CHECK: --> {(1 + (-1 * %offset)),+,1}<nsw>
+; CHECK: --> {(1 + (-1 * %offset))<nsw>,+,1}<nsw>
%index32 = sub nsw i32 %j, %offset
%ptr = getelementptr inbounds float, float* %input, i32 %index32
diff --git a/test/Analysis/ScalarEvolution/guards.ll b/test/Analysis/ScalarEvolution/guards.ll
new file mode 100644
index 0000000000000..52ad4dc73d417
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/guards.ll
@@ -0,0 +1,141 @@
+; RUN: opt -S -indvars < %s | FileCheck %s
+
+; Check that SCEV is able to recognize and use guards to prove
+; conditions gaurding loop entries and backedges. This isn't intended
+; to be a comprehensive test of SCEV's simplification capabilities,
+; tests directly testing e.g. if SCEV can elide a sext should go
+; elsewhere.
+
+target datalayout = "n8:16:32:64"
+
+declare void @llvm.experimental.guard(i1, ...)
+
+define void @test_1(i1* %cond_buf, i32* %len_buf) {
+; CHECK-LABEL: @test_1(
+entry:
+ %len = load i32, i32* %len_buf, !range !{i32 1, i32 2147483648}
+ br label %loop
+
+loop:
+; CHECK: loop:
+; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
+; CHECK: %iv.inc.cmp = icmp slt i32 %iv.inc, %len
+; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
+; CHECK: leave:
+
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add i32 %iv, 1
+
+ %iv.cmp = icmp slt i32 %iv, %len
+ call void(i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ]
+
+ %iv.inc.cmp = icmp slt i32 %iv.inc, %len
+ call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
+
+ %becond = load volatile i1, i1* %cond_buf
+ br i1 %becond, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+define void @test_2(i32 %n, i32* %len_buf) {
+; CHECK-LABEL: @test_2(
+; CHECK: [[LEN_SEXT:%[^ ]+]] = sext i32 %len to i64
+; CHECK: br label %loop
+
+entry:
+ %len = load i32, i32* %len_buf, !range !{i32 0, i32 2147483648}
+ br label %loop
+
+loop:
+; CHECK: loop:
+; CHECK: %indvars.iv = phi i64 [ %indvars.iv.next, %loop ], [ 0, %entry ]
+; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+; CHECK: %iv.inc.cmp = icmp slt i64 %indvars.iv.next, [[LEN_SEXT]]
+; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
+; CHECK: leave:
+
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add i32 %iv, 1
+
+ %iv.sext = sext i32 %iv to i64
+
+ %iv.inc.cmp = icmp slt i32 %iv.inc, %len
+ call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
+
+ %becond = icmp ne i32 %iv, %n
+ br i1 %becond, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+define void @test_3(i1* %cond_buf, i32* %len_buf) {
+; CHECK-LABEL: @test_3(
+
+entry:
+ %len = load i32, i32* %len_buf
+ %entry.cond = icmp sgt i32 %len, 0
+ call void(i1, ...) @llvm.experimental.guard(i1 %entry.cond) [ "deopt"() ]
+ br label %loop
+
+loop:
+; CHECK: loop:
+; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
+; CHECK: %iv.inc.cmp = icmp slt i32 %iv.inc, %len
+; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
+; CHECK: leave:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add i32 %iv, 1
+
+ %iv.cmp = icmp slt i32 %iv, %len
+ call void(i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ]
+
+ %iv.inc.cmp = icmp slt i32 %iv.inc, %len
+ call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
+
+ %becond = load volatile i1, i1* %cond_buf
+ br i1 %becond, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+define void @test_4(i1* %cond_buf, i32* %len_buf) {
+; CHECK-LABEL: @test_4(
+
+entry:
+ %len = load i32, i32* %len_buf
+ %entry.cond = icmp sgt i32 %len, 0
+ call void(i1, ...) @llvm.experimental.guard(i1 %entry.cond) [ "deopt"() ]
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ]
+ %iv.inc = add i32 %iv, 1
+
+ %cond = load volatile i1, i1* %cond_buf
+ br i1 %cond, label %left, label %be
+
+left:
+ ; Does not dominate the backedge, so cannot be used in the inductive proof
+ %iv.inc.cmp = icmp slt i32 %iv.inc, %len
+ call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
+ br label %be
+
+be:
+; CHECK: be:
+; CHECK-NEXT: %iv.cmp = icmp slt i32 %iv, %len
+; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ]
+; CHECK: leave:
+
+ %iv.cmp = icmp slt i32 %iv, %len
+ call void(i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ]
+
+ %becond = load volatile i1, i1* %cond_buf
+ br i1 %becond, label %loop, label %leave
+
+leave:
+ ret void
+}
diff --git a/test/Analysis/ScalarEvolution/incorrect-offset-scaling.ll b/test/Analysis/ScalarEvolution/incorrect-offset-scaling.ll
new file mode 100644
index 0000000000000..7ffb0936d105a
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/incorrect-offset-scaling.ll
@@ -0,0 +1,48 @@
+; RUN: opt -S -loop-reduce < %s | FileCheck %s
+
+target triple = "x86_64-unknown-unknown"
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @incorrect_offset_scaling(i64, i64*) {
+top:
+ br label %L
+
+L: ; preds = %idxend.10, %idxend, %L2, %top
+ br i1 undef, label %L, label %L1
+
+L1: ; preds = %L1.preheader, %L2
+ %r13 = phi i64 [ %r1, %L2 ], [ 1, %L ]
+; CHECK: %lsr.iv = phi i64 [ 0, %L{{[^ ]+}} ], [ %lsr.iv.next, %L2 ]
+; CHECK-NOT: %lsr.iv = phi i64 [ -1, %L{{[^ ]+}} ], [ %lsr.iv.next, %L2 ]
+; CHECK: br
+ %r0 = add i64 %r13, -1
+ br label %idxend.8
+
+L2: ; preds = %idxend.8
+ %r1 = add i64 %r13, 1
+ br i1 undef, label %L, label %L1
+
+if6: ; preds = %idxend.8
+ %r2 = add i64 %0, -1
+ %r3 = load i64, i64* %1, align 8
+; CHECK-NOT: %r2
+; CHECK: %r3 = load i64
+ br label %ib
+
+idxend.8: ; preds = %L1
+ br i1 undef, label %if6, label %L2
+
+ib: ; preds = %if6
+ %r4 = mul i64 %r3, %r0
+ %r5 = add i64 %r2, %r4
+ %r6 = icmp ult i64 %r5, undef
+; CHECK %2 = mul i64 %lsr.iv, %r3
+; CHECK %3 = add i64 %1, -1
+; CHECK %4 = add i64 %0, %r3
+; CHECK %r6
+ %r7 = getelementptr i64, i64* undef, i64 %r5
+ store i64 1, i64* %r7, align 8
+; CHECK %5 = mul i64 %lsr.iv, %r3
+; CHECK %6 = add i64 %5, -1
+ br label %L
+}
diff --git a/test/Analysis/ScalarEvolution/increasing-or-decreasing-iv.ll b/test/Analysis/ScalarEvolution/increasing-or-decreasing-iv.ll
new file mode 100644
index 0000000000000..ae5e360932652
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/increasing-or-decreasing-iv.ll
@@ -0,0 +1,247 @@
+; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s
+
+define void @f0(i1 %c) {
+; CHECK-LABEL: Classifying expressions for: @f0
+entry:
+ %start = select i1 %c, i32 127, i32 0
+ %step = select i1 %c, i32 -1, i32 1
+ br label %loop
+
+loop:
+ %loop.iv = phi i32 [ 0, %entry ], [ %loop.iv.inc, %loop ]
+ %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
+; CHECK: %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
+; CHECK-NEXT: --> {%start,+,%step}<%loop> U: [0,128) S: [0,128)
+ %iv.next = add i32 %iv, %step
+ %loop.iv.inc = add i32 %loop.iv, 1
+ %be.cond = icmp ne i32 %loop.iv.inc, 128
+ br i1 %be.cond, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+define void @f1(i1 %c) {
+; CHECK-LABEL: Classifying expressions for: @f1
+entry:
+ %start = select i1 %c, i32 120, i32 0
+ %step = select i1 %c, i32 -8, i32 8
+ br label %loop
+
+loop:
+ %loop.iv = phi i32 [ 0, %entry ], [ %loop.iv.inc, %loop ]
+ %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
+
+; CHECK: %iv.1 = add i32 %iv, 1
+; CHECK-NEXT: --> {(1 + %start)<nuw><nsw>,+,%step}<%loop> U: [1,122) S: [1,122)
+; CHECK: %iv.2 = add i32 %iv, 2
+; CHECK-NEXT: --> {(2 + %start)<nuw><nsw>,+,%step}<%loop> U: [2,123) S: [2,123)
+; CHECK: %iv.3 = add i32 %iv, 3
+; CHECK-NEXT: --> {(3 + %start)<nuw><nsw>,+,%step}<%loop> U: [3,124) S: [3,124)
+; CHECK: %iv.4 = add i32 %iv, 4
+; CHECK-NEXT: --> {(4 + %start)<nuw><nsw>,+,%step}<%loop> U: [4,125) S: [4,125)
+; CHECK: %iv.5 = add i32 %iv, 5
+; CHECK-NEXT: --> {(5 + %start)<nuw><nsw>,+,%step}<%loop> U: [5,126) S: [5,126)
+; CHECK: %iv.6 = add i32 %iv, 6
+; CHECK-NEXT: --> {(6 + %start)<nuw><nsw>,+,%step}<%loop> U: [6,127) S: [6,127)
+; CHECK: %iv.7 = add i32 %iv, 7
+; CHECK-NEXT: --> {(7 + %start)<nuw><nsw>,+,%step}<%loop> U: [7,128) S: [7,128)
+
+ %iv.1 = add i32 %iv, 1
+ %iv.2 = add i32 %iv, 2
+ %iv.3 = add i32 %iv, 3
+ %iv.4 = add i32 %iv, 4
+ %iv.5 = add i32 %iv, 5
+ %iv.6 = add i32 %iv, 6
+ %iv.7 = add i32 %iv, 7
+
+; CHECK: %iv.m1 = sub i32 %iv, 1
+; CHECK-NEXT: --> {(-1 + %start)<nsw>,+,%step}<%loop> U: [-1,120) S: [-1,120)
+; CHECK: %iv.m2 = sub i32 %iv, 2
+; CHECK-NEXT: --> {(-2 + %start)<nsw>,+,%step}<%loop> U: [-2,119) S: [-2,119)
+; CHECK: %iv.m3 = sub i32 %iv, 3
+; CHECK-NEXT: --> {(-3 + %start)<nsw>,+,%step}<%loop> U: [-3,118) S: [-3,118)
+; CHECK: %iv.m4 = sub i32 %iv, 4
+; CHECK-NEXT: --> {(-4 + %start)<nsw>,+,%step}<%loop> U: [-4,117) S: [-4,117)
+; CHECK: %iv.m5 = sub i32 %iv, 5
+; CHECK-NEXT: --> {(-5 + %start)<nsw>,+,%step}<%loop> U: [-5,116) S: [-5,116)
+; CHECK: %iv.m6 = sub i32 %iv, 6
+; CHECK-NEXT: --> {(-6 + %start)<nsw>,+,%step}<%loop> U: [-6,115) S: [-6,115)
+; CHECK: %iv.m7 = sub i32 %iv, 7
+; CHECK-NEXT: --> {(-7 + %start)<nsw>,+,%step}<%loop> U: [-7,114) S: [-7,114)
+
+ %iv.m1 = sub i32 %iv, 1
+ %iv.m2 = sub i32 %iv, 2
+ %iv.m3 = sub i32 %iv, 3
+ %iv.m4 = sub i32 %iv, 4
+ %iv.m5 = sub i32 %iv, 5
+ %iv.m6 = sub i32 %iv, 6
+ %iv.m7 = sub i32 %iv, 7
+
+ %iv.next = add i32 %iv, %step
+ %loop.iv.inc = add i32 %loop.iv, 1
+ %be.cond = icmp sgt i32 %loop.iv, 14
+ br i1 %be.cond, label %leave, label %loop
+
+leave:
+ ret void
+}
+
+define void @f2(i1 %c) {
+; CHECK-LABEL: Classifying expressions for: @f2
+entry:
+ %start = select i1 %c, i32 127, i32 0
+ %step = select i1 %c, i32 -1, i32 1
+ br label %loop
+
+loop:
+ %loop.iv = phi i32 [ 0, %entry ], [ %loop.iv.inc, %loop ]
+ %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
+ %iv.sext = sext i32 %iv to i64
+ %iv.next = add i32 %iv, %step
+; CHECK: %iv.sext = sext i32 %iv to i64
+; CHECK-NEXT: --> {(sext i32 %start to i64),+,(sext i32 %step to i64)}<nsw><%loop> U: [0,128) S: [0,128)
+ %loop.iv.inc = add i32 %loop.iv, 1
+ %be.cond = icmp ne i32 %loop.iv.inc, 128
+ br i1 %be.cond, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+define void @f3(i1 %c) {
+; CHECK-LABEL: Classifying expressions for: @f3
+entry:
+
+; NB! the i16 type (as opposed to i32), the choice of the constant 509
+; and the trip count are all related and not arbitrary. We want an
+; add recurrence that will look like it can unsign-overflow *unless*
+; SCEV is able to see the correlation between the two selects feeding
+; into the initial value and the step increment.
+
+ %start = select i1 %c, i16 1000, i16 0
+ %step = select i1 %c, i16 1, i16 509
+ br label %loop
+
+loop:
+ %loop.iv = phi i16 [ 0, %entry ], [ %loop.iv.inc, %loop ]
+ %iv = phi i16 [ %start, %entry ], [ %iv.next, %loop ]
+ %iv.zext = zext i16 %iv to i64
+; CHECK: %iv.zext = zext i16 %iv to i64
+; CHECK-NEXT: --> {(zext i16 %start to i64),+,(zext i16 %step to i64)}<nuw><%loop> U: [0,64644) S: [0,64644)
+ %iv.next = add i16 %iv, %step
+ %loop.iv.inc = add i16 %loop.iv, 1
+ %be.cond = icmp ne i16 %loop.iv.inc, 128
+ br i1 %be.cond, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+define void @f4(i1 %c) {
+; CHECK-LABEL: Classifying expressions for: @f4
+
+; @f4() demonstrates a case where SCEV is not able to compute a
+; precise range for %iv.trunc, though it should be able to, in theory.
+; This is because SCEV looks into affine add recurrences only when the
+; backedge taken count of the loop has the same bitwidth as the
+; induction variable.
+entry:
+ %start = select i1 %c, i32 127, i32 0
+ %step = select i1 %c, i32 -1, i32 1
+ br label %loop
+
+loop:
+ %loop.iv = phi i32 [ 0, %entry ], [ %loop.iv.inc, %loop ]
+ %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
+ %iv.trunc = trunc i32 %iv to i16
+; CHECK: %iv.trunc = trunc i32 %iv to i16
+; CHECK-NEXT: --> {(trunc i32 %start to i16),+,(trunc i32 %step to i16)}<%loop> U: full-set S: full-set
+ %iv.next = add i32 %iv, %step
+ %loop.iv.inc = add i32 %loop.iv, 1
+ %be.cond = icmp ne i32 %loop.iv.inc, 128
+ br i1 %be.cond, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+define void @f5(i1 %c) {
+; CHECK-LABEL: Classifying expressions for: @f5
+entry:
+ %start = select i1 %c, i32 127, i32 0
+ %step = select i1 %c, i32 -1, i32 1
+ br label %loop
+
+loop:
+ %loop.iv = phi i16 [ 0, %entry ], [ %loop.iv.inc, %loop ]
+ %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
+ %iv.trunc = trunc i32 %iv to i16
+; CHECK: %iv.trunc = trunc i32 %iv to i16
+; CHECK-NEXT: --> {(trunc i32 %start to i16),+,(trunc i32 %step to i16)}<%loop> U: [0,128) S: [0,128)
+ %iv.next = add i32 %iv, %step
+
+ %loop.iv.inc = add i16 %loop.iv, 1
+ %be.cond = icmp ne i16 %loop.iv.inc, 128
+ br i1 %be.cond, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+define void @f6(i1 %c) {
+; CHECK-LABEL: Classifying expressions for: @f6
+entry:
+ %start = select i1 %c, i32 127, i32 0
+ %step = select i1 %c, i32 -2, i32 0
+ br label %loop
+
+loop:
+ %loop.iv = phi i16 [ 0, %entry ], [ %loop.iv.inc, %loop ]
+ %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
+; CHECK: %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
+; CHECK-NEXT: --> {%start,+,(1 + %step)<nuw><nsw>}<%loop> U: [0,128) S: [0,128)
+
+ %step.plus.one = add i32 %step, 1
+ %iv.next = add i32 %iv, %step.plus.one
+ %iv.sext = sext i32 %iv to i64
+; CHECK: %iv.sext = sext i32 %iv to i64
+; CHECK-NEXT: --> {(sext i32 %start to i64),+,(1 + (sext i32 %step to i64))<nsw>}<nsw><%loop> U: [0,128) S: [0,128)
+ %loop.iv.inc = add i16 %loop.iv, 1
+ %be.cond = icmp ne i16 %loop.iv.inc, 128
+ br i1 %be.cond, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+define void @f7(i1 %c) {
+; CHECK-LABEL: Classifying expressions for: @f7
+entry:
+ %start = select i1 %c, i32 127, i32 0
+ %step = select i1 %c, i32 -1, i32 1
+ br label %loop
+
+loop:
+ %loop.iv = phi i16 [ 0, %entry ], [ %loop.iv.inc, %loop ]
+ %iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
+ %iv.trunc = trunc i32 %iv to i16
+; CHECK: %iv.trunc = trunc i32 %iv to i16
+; CHECK-NEXT: --> {(trunc i32 %start to i16),+,(trunc i32 %step to i16)}<%loop> U: [0,128) S: [0,128)
+ %iv.next = add i32 %iv, %step
+
+ %iv.trunc.plus.one = add i16 %iv.trunc, 1
+; CHECK: %iv.trunc.plus.one = add i16 %iv.trunc, 1
+; CHECK-NEXT: --> {(1 + (trunc i32 %start to i16))<nuw><nsw>,+,(trunc i32 %step to i16)}<%loop> U: [1,129) S: [1,129)
+
+ %iv.trunc.plus.two = add i16 %iv.trunc, 2
+; CHECK: %iv.trunc.plus.two = add i16 %iv.trunc, 2
+; CHECK-NEXT: --> {(2 + (trunc i32 %start to i16))<nuw><nsw>,+,(trunc i32 %step to i16)}<%loop> U: [2,130) S: [2,130)
+
+ %loop.iv.inc = add i16 %loop.iv, 1
+ %be.cond = icmp ne i16 %loop.iv.inc, 128
+ br i1 %be.cond, label %loop, label %leave
+
+leave:
+ ret void
+}
diff --git a/test/Analysis/ScalarEvolution/infer-prestart-no-wrap.ll b/test/Analysis/ScalarEvolution/infer-prestart-no-wrap.ll
index 5c372b5d7b8a1..f28e66716e1a5 100644
--- a/test/Analysis/ScalarEvolution/infer-prestart-no-wrap.ll
+++ b/test/Analysis/ScalarEvolution/infer-prestart-no-wrap.ll
@@ -1,6 +1,6 @@
; ; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s
-define void @infer.sext.0(i1* %c, i32 %start) {
+define void @infer.sext.0(i1* %c, i32 %start, i32* %buf) {
; CHECK-LABEL: Classifying expressions for: @infer.sext.0
entry:
br label %loop
@@ -12,6 +12,10 @@ define void @infer.sext.0(i1* %c, i32 %start) {
%idx.inc.sext = sext i32 %idx.inc to i64
; CHECK: %idx.inc.sext = sext i32 %idx.inc to i64
; CHECK-NEXT: --> {(1 + (sext i32 %start to i64))<nsw>,+,1}<nsw><%loop>
+
+ %buf.gep = getelementptr inbounds i32, i32* %buf, i32 %idx.inc
+ %val = load i32, i32* %buf.gep
+
%condition = icmp eq i32 %counter, 1
%counter.inc = add i32 %counter, 1
br i1 %condition, label %exit, label %loop
@@ -20,7 +24,7 @@ define void @infer.sext.0(i1* %c, i32 %start) {
ret void
}
-define void @infer.zext.0(i1* %c, i32 %start) {
+define void @infer.zext.0(i1* %c, i32 %start, i32* %buf) {
; CHECK-LABEL: Classifying expressions for: @infer.zext.0
entry:
br label %loop
@@ -32,6 +36,10 @@ define void @infer.zext.0(i1* %c, i32 %start) {
%idx.inc.sext = zext i32 %idx.inc to i64
; CHECK: %idx.inc.sext = zext i32 %idx.inc to i64
; CHECK-NEXT: --> {(1 + (zext i32 %start to i64))<nuw><nsw>,+,1}<nuw><%loop>
+
+ %buf.gep = getelementptr inbounds i32, i32* %buf, i32 %idx.inc
+ %val = load i32, i32* %buf.gep
+
%condition = icmp eq i32 %counter, 1
%counter.inc = add i32 %counter, 1
br i1 %condition, label %exit, label %loop
diff --git a/test/Analysis/ScalarEvolution/no-wrap-unknown-becount.ll b/test/Analysis/ScalarEvolution/no-wrap-unknown-becount.ll
new file mode 100644
index 0000000000000..1f972f3f6d932
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/no-wrap-unknown-becount.ll
@@ -0,0 +1,124 @@
+; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s
+
+declare void @llvm.experimental.guard(i1, ...)
+declare void @llvm.assume(i1)
+
+define void @s_0(i32 %n, i1* %cond) {
+; CHECK-LABEL: Classifying expressions for: @s_0
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add i32 %iv, 1
+ %iv.sext = sext i32 %iv to i64
+; CHECK: %iv.sext = sext i32 %iv to i64
+; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop>
+ %cmp = icmp slt i32 %iv, %n
+ call void(i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
+ %c = load volatile i1, i1* %cond
+ br i1 %c, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+define void @s_1(i1* %cond) {
+; CHECK-LABEL: Classifying expressions for: @s_1
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add i32 %iv, 3
+ %iv.sext = sext i32 %iv to i64
+; CHECK: %iv.sext = sext i32 %iv to i64
+; CHECK-NEXT: --> {0,+,3}<nuw><nsw><%loop>
+ %cmp = icmp slt i32 %iv, 10000
+ call void(i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
+ %c = load volatile i1, i1* %cond
+ br i1 %c, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+define void @s_2(i1* %cond) {
+; CHECK-LABEL: Classifying expressions for: @s_2
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add i32 %iv, 3
+ %iv.sext = sext i32 %iv to i64
+ %cmp = icmp slt i32 %iv, 10000
+; CHECK: %iv.sext = sext i32 %iv to i64
+; CHECK-NEXT: --> {0,+,3}<nuw><nsw><%loop>
+ call void @llvm.assume(i1 %cmp)
+ %c = load volatile i1, i1* %cond
+ br i1 %c, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+define void @u_0(i32 %n, i1* %cond) {
+; CHECK-LABEL: Classifying expressions for: @u_0
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add i32 %iv, 1
+ %iv.zext = zext i32 %iv to i64
+; CHECK: %iv.zext = zext i32 %iv to i64
+; CHECK-NEXT: --> {0,+,1}<nuw><%loop>
+ %cmp = icmp ult i32 %iv, %n
+ call void(i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
+ %c = load volatile i1, i1* %cond
+ br i1 %c, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+define void @u_1(i1* %cond) {
+; CHECK-LABEL: Classifying expressions for: @u_1
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add i32 %iv, 3
+ %iv.zext = zext i32 %iv to i64
+; CHECK: %iv.zext = zext i32 %iv to i64
+; CHECK-NEXT: --> {0,+,3}<nuw><%loop>
+ %cmp = icmp ult i32 %iv, 10000
+ call void(i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
+ %c = load volatile i1, i1* %cond
+ br i1 %c, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+define void @u_2(i1* %cond) {
+; CHECK-LABEL: Classifying expressions for: @u_2
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 30000, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add i32 %iv, -2
+ %iv.zext = zext i32 %iv to i64
+ %cmp = icmp ugt i32 %iv.inc, -10000
+; CHECK: %iv.zext = zext i32 %iv to i64
+; CHECK-NEXT: --> {30000,+,-2}<nw><%loop>
+ call void @llvm.assume(i1 %cmp)
+ %c = load volatile i1, i1* %cond
+ br i1 %c, label %loop, label %leave
+
+leave:
+ ret void
+}
diff --git a/test/Analysis/ScalarEvolution/nowrap-preinc-limits.ll b/test/Analysis/ScalarEvolution/nowrap-preinc-limits.ll
index 1a5409d01f641..fa5ab82e064c6 100644
--- a/test/Analysis/ScalarEvolution/nowrap-preinc-limits.ll
+++ b/test/Analysis/ScalarEvolution/nowrap-preinc-limits.ll
@@ -36,7 +36,8 @@ define void @g(i1* %condition) {
; CHECK: %idx.inc2.sext = sext i32 %idx.inc2 to i64
; CHECK-NEXT: --> {2,+,3}<nuw><nsw><%loop>
- %c = load volatile i1, i1* %condition
+ %cond.gep = getelementptr inbounds i1, i1* %condition, i32 %idx.inc
+ %c = load volatile i1, i1* %cond.gep
br i1 %c, label %loop, label %exit
exit:
diff --git a/test/Analysis/ScalarEvolution/nsw-offset-assume.ll b/test/Analysis/ScalarEvolution/nsw-offset-assume.ll
index bef1070bbcb04..5413b477df589 100644
--- a/test/Analysis/ScalarEvolution/nsw-offset-assume.ll
+++ b/test/Analysis/ScalarEvolution/nsw-offset-assume.ll
@@ -39,7 +39,7 @@ bb: ; preds = %bb.nph, %bb1
%8 = sext i32 %7 to i64 ; <i64> [#uses=1]
; CHECK: %9 = getelementptr inbounds double, double* %q, i64 %8
-; CHECK: {(8 + %q),+,16}<nsw><%bb>
+; CHECK: {(8 + %q)<nsw>,+,16}<nsw><%bb>
%9 = getelementptr inbounds double, double* %q, i64 %8 ; <double*> [#uses=1]
; Artificially repeat the above three instructions, this time using
@@ -51,7 +51,7 @@ bb: ; preds = %bb.nph, %bb1
%t8 = sext i32 %t7 to i64 ; <i64> [#uses=1]
; CHECK: %t9 = getelementptr inbounds double, double* %q, i64 %t8
-; CHECK: {(8 + %q),+,16}<nsw><%bb>
+; CHECK: {(8 + %q)<nsw>,+,16}<nsw><%bb>
%t9 = getelementptr inbounds double, double* %q, i64 %t8 ; <double*> [#uses=1]
%10 = load double, double* %9, align 8 ; <double> [#uses=1]
diff --git a/test/Analysis/ScalarEvolution/nsw-offset.ll b/test/Analysis/ScalarEvolution/nsw-offset.ll
index 127bb19bff025..f8ed8f003ff1e 100644
--- a/test/Analysis/ScalarEvolution/nsw-offset.ll
+++ b/test/Analysis/ScalarEvolution/nsw-offset.ll
@@ -37,7 +37,7 @@ bb: ; preds = %bb.nph, %bb1
%8 = sext i32 %7 to i64 ; <i64> [#uses=1]
; CHECK: %9 = getelementptr inbounds double, double* %q, i64 %8
-; CHECK: {(8 + %q),+,16}<nsw><%bb>
+; CHECK: {(8 + %q)<nsw>,+,16}<nsw><%bb>
%9 = getelementptr inbounds double, double* %q, i64 %8 ; <double*> [#uses=1]
; Artificially repeat the above three instructions, this time using
@@ -49,7 +49,7 @@ bb: ; preds = %bb.nph, %bb1
%t8 = sext i32 %t7 to i64 ; <i64> [#uses=1]
; CHECK: %t9 = getelementptr inbounds double, double* %q, i64 %t8
-; CHECK: {(8 + %q),+,16}<nsw><%bb>
+; CHECK: {(8 + %q)<nsw>,+,16}<nsw><%bb>
%t9 = getelementptr inbounds double, double* %q, i64 %t8 ; <double*> [#uses=1]
%10 = load double, double* %9, align 8 ; <double> [#uses=1]
diff --git a/test/Analysis/ScalarEvolution/nsw.ll b/test/Analysis/ScalarEvolution/nsw.ll
index 15444e38b83cb..a3752919d334d 100644
--- a/test/Analysis/ScalarEvolution/nsw.ll
+++ b/test/Analysis/ScalarEvolution/nsw.ll
@@ -30,15 +30,17 @@ bb: ; preds = %bb1, %bb.nph
%tmp8 = add nsw i32 %i.01, 1 ; <i32> [#uses=2]
; CHECK: %tmp8
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%bb>
+ %p.gep = getelementptr double, double* %p, i32 %tmp8
+ %p.val = load double, double* %p.gep
br label %bb1
bb1: ; preds = %bb
%phitmp = sext i32 %tmp8 to i64 ; <i64> [#uses=1]
; CHECK: %phitmp
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%bb>
- %tmp9 = getelementptr double, double* %p, i64 %phitmp ; <double*> [#uses=1]
+ %tmp9 = getelementptr inbounds double, double* %p, i64 %phitmp ; <double*> [#uses=1]
; CHECK: %tmp9
-; CHECK-NEXT: --> {(8 + %p),+,8}<%bb>
+; CHECK-NEXT: --> {(8 + %p)<nsw>,+,8}<nsw><%bb>
%tmp10 = load double, double* %tmp9, align 8 ; <double> [#uses=1]
%tmp11 = fcmp ogt double %tmp10, 2.000000e+00 ; <i1> [#uses=1]
br i1 %tmp11, label %bb, label %bb1.return_crit_edge
@@ -66,7 +68,7 @@ for.body.i.i: ; preds = %for.body.i.i, %for.
store i32 0, i32* %__first.addr.02.i.i, align 4
%ptrincdec.i.i = getelementptr inbounds i32, i32* %__first.addr.02.i.i, i64 1
; CHECK: %ptrincdec.i.i
-; CHECK-NEXT: --> {(4 + %begin),+,4}<nuw><%for.body.i.i>
+; CHECK-NEXT: --> {(4 + %begin)<nsw>,+,4}<nuw><%for.body.i.i>
%cmp.i.i = icmp eq i32* %ptrincdec.i.i, %end
br i1 %cmp.i.i, label %for.cond.for.end_crit_edge.i.i, label %for.body.i.i
@@ -92,7 +94,7 @@ for.body.i.i: ; preds = %entry, %for.body.i.
; CHECK: {1,+,1}<nuw><nsw><%for.body.i.i>
%ptrincdec.i.i = getelementptr inbounds i32, i32* %begin, i64 %tmp
; CHECK: %ptrincdec.i.i =
-; CHECK: {(4 + %begin),+,4}<nsw><%for.body.i.i>
+; CHECK: {(4 + %begin)<nsw>,+,4}<nsw><%for.body.i.i>
%__first.addr.08.i.i = getelementptr inbounds i32, i32* %begin, i64 %indvar.i.i
; CHECK: %__first.addr.08.i.i
; CHECK: {%begin,+,4}<nsw><%for.body.i.i>
@@ -124,7 +126,7 @@ exit:
}
; CHECK-LABEL: PR12375
-; CHECK: --> {(4 + %arg),+,4}<nuw><%bb1>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (8 + %arg)<nsw>
+; CHECK: --> {(4 + %arg)<nsw>,+,4}<nuw><%bb1>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (4 + (4 * ((-1 + (-1 * %arg) + ((4 + %arg)<nsw> umax (8 + %arg)<nsw>)) /u 4)) + %arg)
define i32 @PR12375(i32* readnone %arg) {
bb:
%tmp = getelementptr inbounds i32, i32* %arg, i64 2
@@ -143,15 +145,15 @@ bb7: ; preds = %bb1
}
; CHECK-LABEL: PR12376
-; CHECK: --> {(4 + %arg),+,4}<nuw><%bb2>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (4 + (4 * ((3 + (-1 * %arg) + (%arg umax %arg1)) /u 4)) + %arg)
+; CHECK: --> {(4 + %arg)<nsw>,+,4}<nuw><%bb2>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (4 + (4 * ((-1 + (-1 * %arg) + ((4 + %arg)<nsw> umax %arg1)) /u 4)) + %arg)
define void @PR12376(i32* nocapture %arg, i32* nocapture %arg1) {
bb:
br label %bb2
bb2: ; preds = %bb2, %bb
%tmp = phi i32* [ %arg, %bb ], [ %tmp4, %bb2 ]
- %tmp3 = icmp ult i32* %tmp, %arg1
%tmp4 = getelementptr inbounds i32, i32* %tmp, i64 1
+ %tmp3 = icmp ult i32* %tmp4, %arg1
br i1 %tmp3, label %bb2, label %bb5
bb5: ; preds = %bb2
@@ -161,8 +163,8 @@ bb5: ; preds = %bb2
declare void @f(i32)
; CHECK-LABEL: nswnowrap
-; CHECK: --> {(1 + %v),+,1}<nsw><%for.body>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (2 + %v)
-define void @nswnowrap(i32 %v) {
+; CHECK: --> {(1 + %v)<nsw>,+,1}<nsw><%for.body>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (1 + ((1 + %v)<nsw> smax %v))
+define void @nswnowrap(i32 %v, i32* %buf) {
entry:
%add = add nsw i32 %v, 1
br label %for.body
@@ -170,10 +172,91 @@ entry:
for.body:
%i.04 = phi i32 [ %v, %entry ], [ %inc, %for.body ]
%inc = add nsw i32 %i.04, 1
- tail call void @f(i32 %i.04)
+ %buf.gep = getelementptr inbounds i32, i32* %buf, i32 %inc
+ %buf.val = load i32, i32* %buf.gep
%cmp = icmp slt i32 %i.04, %add
+ tail call void @f(i32 %i.04)
br i1 %cmp, label %for.body, label %for.end
for.end:
ret void
}
+
+; This test checks if no-wrap flags are propagated when folding {S,+,X}+T ==> {S+T,+,X}
+; CHECK-LABEL: test4
+; CHECK: %idxprom
+; CHECK-NEXT: --> {(-2 + (sext i32 %arg to i64))<nsw>,+,1}<nsw><%for.body>
+define void @test4(i32 %arg) {
+entry:
+ %array = alloca [10 x i32], align 4
+ br label %for.body
+
+for.body:
+ %index = phi i32 [ %inc5, %for.body ], [ %arg, %entry ]
+ %sub = add nsw i32 %index, -2
+ %idxprom = sext i32 %sub to i64
+ %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %array, i64 0, i64 %idxprom
+ %data = load i32, i32* %arrayidx, align 4
+ %inc5 = add nsw i32 %index, 1
+ %cmp2 = icmp slt i32 %inc5, 10
+ br i1 %cmp2, label %for.body, label %for.end
+
+for.end:
+ ret void
+}
+
+
+define void @bad_postinc_nsw_a(i32 %n) {
+; CHECK-LABEL: Classifying expressions for: @bad_postinc_nsw_a
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add nsw i32 %iv, 7
+; CHECK: %iv.inc = add nsw i32 %iv, 7
+; CHECK-NEXT: --> {7,+,7}<nuw><%loop>
+ %becond = icmp ult i32 %iv, %n
+ br i1 %becond, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+define void @bad_postinc_nsw_b(i32 %n) {
+; CHECK-LABEL: Classifying expressions for: @bad_postinc_nsw_b
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add nsw i32 %iv, 7
+ %iv.inc.and = and i32 %iv.inc, 0
+; CHECK: %iv.inc = add nsw i32 %iv, 7
+; CHECK-NEXT: --> {7,+,7}<nuw><%loop>
+ %becond = icmp ult i32 %iv.inc.and, %n
+ br i1 %becond, label %loop, label %leave
+
+leave:
+ ret void
+}
+
+declare void @may_exit() nounwind
+
+define void @pr28012(i32 %n) {
+; CHECK-LABEL: Classifying expressions for: @pr28012
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add nsw i32 %iv, 7
+; CHECK: %iv.inc = add nsw i32 %iv, 7
+; CHECK-NEXT: --> {7,+,7}<nuw><%loop>
+ %becond = icmp ult i32 %iv.inc, %n
+ call void @may_exit()
+ br i1 %becond, label %loop, label %leave
+
+leave:
+ ret void
+}
diff --git a/test/Analysis/ScalarEvolution/overflow-intrinsics.ll b/test/Analysis/ScalarEvolution/overflow-intrinsics.ll
new file mode 100644
index 0000000000000..fb3d816c9fab4
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/overflow-intrinsics.ll
@@ -0,0 +1,309 @@
+; RUN: opt -analyze -scalar-evolution < %s | 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 @f_sadd_0(i8* %a) {
+; CHECK-LABEL: Classifying expressions for: @f_sadd_0
+entry:
+ br label %for.body
+
+for.cond.cleanup: ; preds = %cont
+ ret void
+
+for.body: ; preds = %entry, %cont
+; CHECK: %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
+; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%for.body> U: [0,16) S: [0,16)
+
+ %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
+ %idxprom = sext i32 %i.04 to i64
+ %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
+ store i8 0, i8* %arrayidx, align 1
+ %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
+ %tmp1 = extractvalue { i32, i1 } %tmp0, 1
+ br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
+
+trap: ; preds = %for.body
+ tail call void @llvm.trap() #2, !nosanitize !{}
+ unreachable, !nosanitize !{}
+
+cont: ; preds = %for.body
+ %tmp2 = extractvalue { i32, i1 } %tmp0, 0
+ %cmp = icmp slt i32 %tmp2, 16
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+; CHECK: Loop %for.body: max backedge-taken count is 15
+}
+
+define void @f_sadd_1(i8* %a) {
+; CHECK-LABEL: Classifying expressions for: @f_sadd_1
+entry:
+ br label %for.body
+
+for.cond.cleanup: ; preds = %cont
+ ret void
+
+for.body: ; preds = %entry, %cont
+; CHECK: %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
+; CHECK-NEXT: --> {0,+,1}<%for.body> U: [0,16) S: [0,16)
+
+; SCEV can prove <nsw> for the above induction variable; but it does
+; not bother so before it sees the sext below since it is not a 100%
+; obvious.
+
+ %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
+ %idxprom = sext i32 %i.04 to i64
+ %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
+ store i8 0, i8* %arrayidx, align 1
+ %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
+ %tmp1 = extractvalue { i32, i1 } %tmp0, 1
+ br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
+
+trap: ; preds = %for.body
+
+ br label %cont
+
+cont: ; preds = %for.body
+ %tmp2 = extractvalue { i32, i1 } %tmp0, 0
+ %cmp = icmp slt i32 %tmp2, 16
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+; CHECK: Loop %for.body: max backedge-taken count is 15
+}
+
+define void @f_sadd_2(i8* %a, i1* %c) {
+; CHECK-LABEL: Classifying expressions for: @f_sadd_2
+entry:
+ br label %for.body
+
+for.cond.cleanup: ; preds = %cont
+ ret void
+
+for.body: ; preds = %entry, %cont
+; CHECK: %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
+; CHECK-NEXT: --> {0,+,1}<%for.body>
+
+ %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
+ %idxprom = sext i32 %i.04 to i64
+ %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
+ store i8 0, i8* %arrayidx, align 1
+ %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
+ %tmp1 = extractvalue { i32, i1 } %tmp0, 1
+ br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
+
+trap: ; preds = %for.body
+
+ br label %cont
+
+cont: ; preds = %for.body
+ %tmp2 = extractvalue { i32, i1 } %tmp0, 0
+ %cond = load volatile i1, i1* %c
+ br i1 %cond, label %for.body, label %for.cond.cleanup
+}
+
+define void @f_sadd_3(i8* %a, i1* %c) {
+; CHECK-LABEL: Classifying expressions for: @f_sadd_3
+entry:
+ br label %for.body
+
+for.cond.cleanup: ; preds = %cont
+ ret void
+
+for.body: ; preds = %entry, %cont
+; CHECK: %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %for.body ]
+; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%for.body>
+
+ %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %for.body ]
+ %idxprom = sext i32 %i.04 to i64
+ %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
+ store i8 0, i8* %arrayidx, align 1
+ %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
+ %tmp1 = extractvalue { i32, i1 } %tmp0, 1
+ %tmp2 = extractvalue { i32, i1 } %tmp0, 0
+ br i1 %tmp1, label %trap, label %for.body, !nosanitize !{}
+
+trap: ; preds = %for.body
+ tail call void @llvm.trap() #2, !nosanitize !{}
+ unreachable, !nosanitize !{}
+}
+
+define void @f_sadd_4(i8* %a, i1* %c) {
+; CHECK-LABEL: Classifying expressions for: @f_sadd_4
+entry:
+ br label %for.body
+
+for.cond.cleanup: ; preds = %cont
+ ret void
+
+for.body: ; preds = %entry, %cont
+; CHECK: %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %merge ]
+; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%for.body>
+
+ %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %merge ]
+ %idxprom = sext i32 %i.04 to i64
+ %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
+ store i8 0, i8* %arrayidx, align 1
+ %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
+ %tmp1 = extractvalue { i32, i1 } %tmp0, 1
+ %tmp2 = extractvalue { i32, i1 } %tmp0, 0
+ br i1 %tmp1, label %notrap, label %merge
+
+notrap:
+ br label %merge
+
+merge:
+ %tmp3 = extractvalue { i32, i1 } %tmp0, 1
+ br i1 %tmp3, label %trap, label %for.body, !nosanitize !{}
+
+trap: ; preds = %for.body
+ tail call void @llvm.trap() #2, !nosanitize !{}
+ unreachable, !nosanitize !{}
+}
+
+define void @f_sadd_may_overflow(i8* %a, i1* %c) {
+; CHECK-LABEL: Classifying expressions for: @f_sadd_may_overflow
+entry:
+ br label %for.body
+
+for.cond.cleanup: ; preds = %cont
+ ret void
+
+for.body: ; preds = %entry, %cont
+; CHECK: %i.04 = phi i32 [ 0, %entry ], [ %tmp1, %cont ]
+; CHECK-NEXT: --> {0,+,1}<%for.body> U: full-set S: full-set
+
+ %i.04 = phi i32 [ 0, %entry ], [ %tmp1, %cont ]
+ %idxprom = sext i32 %i.04 to i64
+ %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
+ store i8 0, i8* %arrayidx, align 1
+ %tmp0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
+ %cond1 = load volatile i1, i1* %c
+ br i1 %cond1, label %trap, label %cont, !nosanitize !{}
+
+trap: ; preds = %for.body
+ tail call void @llvm.trap() #2, !nosanitize !{}
+ unreachable, !nosanitize !{}
+
+cont: ; preds = %for.body
+ %tmp1 = extractvalue { i32, i1 } %tmp0, 0
+ %cond = load volatile i1, i1* %c
+ br i1 %cond, label %for.body, label %for.cond.cleanup
+}
+
+define void @f_uadd(i8* %a) {
+; CHECK-LABEL: Classifying expressions for: @f_uadd
+entry:
+ br label %for.body
+
+for.cond.cleanup: ; preds = %cont
+ ret void
+
+for.body: ; preds = %entry, %cont
+; CHECK: %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
+; CHECK-NEXT: --> {0,+,1}<nuw><%for.body> U: [0,16) S: [0,16)
+
+ %i.04 = phi i32 [ 0, %entry ], [ %tmp2, %cont ]
+ %idxprom = sext i32 %i.04 to i64
+ %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
+ store i8 0, i8* %arrayidx, align 1
+ %tmp0 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %i.04, i32 1)
+ %tmp1 = extractvalue { i32, i1 } %tmp0, 1
+ br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
+
+trap: ; preds = %for.body
+ tail call void @llvm.trap(), !nosanitize !{}
+ unreachable, !nosanitize !{}
+
+cont: ; preds = %for.body
+ %tmp2 = extractvalue { i32, i1 } %tmp0, 0
+ %cmp = icmp slt i32 %tmp2, 16
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+; CHECK: Loop %for.body: max backedge-taken count is 15
+}
+
+define void @f_ssub(i8* nocapture %a) {
+; CHECK-LABEL: Classifying expressions for: @f_ssub
+entry:
+ br label %for.body
+
+for.cond.cleanup: ; preds = %cont
+ ret void
+
+for.body: ; preds = %entry, %cont
+; CHECK: %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
+; CHECK-NEXT: --> {15,+,-1}<%for.body> U: [0,16) S: [0,16)
+
+ %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
+ %idxprom = sext i32 %i.04 to i64
+ %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
+ store i8 0, i8* %arrayidx, align 1
+ %tmp0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %i.04, i32 1)
+ %tmp1 = extractvalue { i32, i1 } %tmp0, 1
+ br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
+
+trap: ; preds = %for.body
+ tail call void @llvm.trap(), !nosanitize !{}
+ unreachable, !nosanitize !{}
+
+cont: ; preds = %for.body
+ %tmp2 = extractvalue { i32, i1 } %tmp0, 0
+ %cmp = icmp sgt i32 %tmp2, -1
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+; CHECK: Loop %for.body: max backedge-taken count is 15
+}
+
+define void @f_usub(i8* nocapture %a) {
+; CHECK-LABEL: Classifying expressions for: @f_usub
+entry:
+ br label %for.body
+
+for.cond.cleanup: ; preds = %cont
+ ret void
+
+for.body: ; preds = %entry, %cont
+; CHECK: %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
+; CHECK-NEXT: --> {15,+,-1}<%for.body> U: [0,16) S: [0,16)
+
+ %i.04 = phi i32 [ 15, %entry ], [ %tmp2, %cont ]
+ %idxprom = sext i32 %i.04 to i64
+ %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom
+ store i8 0, i8* %arrayidx, align 1
+ %tmp0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %i.04, i32 1)
+ %tmp1 = extractvalue { i32, i1 } %tmp0, 1
+ br i1 %tmp1, label %trap, label %cont, !nosanitize !{}
+
+trap: ; preds = %for.body
+ tail call void @llvm.trap(), !nosanitize !{}
+ unreachable, !nosanitize !{}
+
+cont: ; preds = %for.body
+ %tmp2 = extractvalue { i32, i1 } %tmp0, 0
+ %cmp = icmp sgt i32 %tmp2, -1
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+; CHECK: Loop %for.body: max backedge-taken count is 15
+}
+
+define i32 @f_smul(i32 %val_a, i32 %val_b) {
+; CHECK-LABEL: Classifying expressions for: @f_smul
+ %agg = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %val_a, i32 %val_b)
+; CHECK: %mul = extractvalue { i32, i1 } %agg, 0
+; CHECK-NEXT: --> (%val_a * %val_b) U: full-set S: full-set
+ %mul = extractvalue { i32, i1 } %agg, 0
+ ret i32 %mul
+}
+
+define i32 @f_umul(i32 %val_a, i32 %val_b) {
+; CHECK-LABEL: Classifying expressions for: @f_umul
+ %agg = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %val_a, i32 %val_b)
+; CHECK: %mul = extractvalue { i32, i1 } %agg, 0
+; CHECK-NEXT: --> (%val_a * %val_b) U: full-set S: full-set
+ %mul = extractvalue { i32, i1 } %agg, 0
+ ret i32 %mul
+}
+
+declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
+declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
+declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
+declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
+declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
+declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
+
+declare void @llvm.trap() #2
diff --git a/test/Analysis/ScalarEvolution/pr27315.ll b/test/Analysis/ScalarEvolution/pr27315.ll
new file mode 100644
index 0000000000000..8f5f79df563b9
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/pr27315.ll
@@ -0,0 +1,31 @@
+; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s
+
+declare i1 @use(i64)
+
+define void @f_0() {
+; CHECK-LABEL: Classifying expressions for: @f_0
+
+; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.inc.nowrap, %be ]
+; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop>
+; CHECK: %iv.inc.maywrap = add i32 %iv, 1
+; CHECK-NEXT: --> {1,+,1}<nuw><%loop>
+; CHECK: %iv.inc.maywrap.sext = sext i32 %iv.inc.maywrap to i64
+; CHECK-NEXT: --> (sext i32 {1,+,1}<nuw><%loop> to i64)
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc.nowrap, %be ]
+ %iv.inc.maywrap = add i32 %iv, 1
+ %iv.inc.maywrap.sext = sext i32 %iv.inc.maywrap to i64
+ %cond0 = call i1 @use(i64 %iv.inc.maywrap.sext)
+ br i1 %cond0, label %be, label %leave
+
+be:
+ %iv.inc.nowrap = add nsw i32 %iv, 1
+ %be.cond = call i1 @use(i64 0) ;; Get an unanalyzable value
+ br i1 %be.cond, label %loop, label %leave
+
+leave:
+ ret void
+}
diff --git a/test/Analysis/ScalarEvolution/predicated-trip-count.ll b/test/Analysis/ScalarEvolution/predicated-trip-count.ll
new file mode 100644
index 0000000000000..2db0a8b577745
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/predicated-trip-count.ll
@@ -0,0 +1,109 @@
+; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+@A = weak global [1000 x i32] zeroinitializer, align 32
+
+; The resulting predicate is i16 {0,+,1} <nssw>, meanining
+; that the resulting backedge expression will be valid for:
+; (1 + (-1 smax %M)) <= MAX_INT16
+;
+; At the limit condition for M (MAX_INT16 - 1) we have in the
+; last iteration:
+; i0 <- MAX_INT16
+; i0.ext <- MAX_INT16
+;
+; and therefore no wrapping happend for i0 or i0.ext
+; throughout the execution of the loop. The resulting predicated
+; backedge taken count is correct.
+
+; CHECK: Classifying expressions for: @test1
+; CHECK: %i.0.ext = sext i16 %i.0 to i32
+; CHECK-NEXT: --> (sext i16 {0,+,1}<%bb3> to i32)
+; CHECK: Loop %bb3: Unpredictable backedge-taken count.
+; CHECK-NEXT: Loop %bb3: Unpredictable max backedge-taken count.
+; CHECK-NEXT: Loop %bb3: Predicated backedge-taken count is (1 + (-1 smax %M))
+; CHECK-NEXT: Predicates:
+; CHECK-NEXT: {0,+,1}<%bb3> Added Flags: <nssw>
+define void @test1(i32 %N, i32 %M) {
+entry:
+ br label %bb3
+
+bb: ; preds = %bb3
+ %tmp = getelementptr [1000 x i32], [1000 x i32]* @A, i32 0, i16 %i.0 ; <i32*> [#uses=1]
+ store i32 123, i32* %tmp
+ %tmp2 = add i16 %i.0, 1 ; <i32> [#uses=1]
+ br label %bb3
+
+bb3: ; preds = %bb, %entry
+ %i.0 = phi i16 [ 0, %entry ], [ %tmp2, %bb ] ; <i32> [#uses=3]
+ %i.0.ext = sext i16 %i.0 to i32
+ %tmp3 = icmp sle i32 %i.0.ext, %M ; <i1> [#uses=1]
+ br i1 %tmp3, label %bb, label %bb5
+
+bb5: ; preds = %bb3
+ br label %return
+
+return: ; preds = %bb5
+ ret void
+}
+
+; The predicated backedge taken count is:
+; (2 + (zext i16 %Start to i32) + ((-2 + (-1 * (sext i16 %Start to i32)))
+; smax (-1 + (-1 * %M)))
+; )
+
+; -1 + (-1 * %M) <= (-2 + (-1 * (sext i16 %Start to i32))
+; The predicated backedge taken count is 0.
+; From the IR, this is correct since we will bail out at the
+; first iteration.
+
+
+; * -1 + (-1 * %M) > (-2 + (-1 * (sext i16 %Start to i32))
+; or: %M < 1 + (sext i16 %Start to i32)
+;
+; The predicated backedge taken count is 1 + (zext i16 %Start to i32) - %M
+;
+; If %M >= MIN_INT + 1, this predicated backedge taken count would be correct (even
+; without predicates). However, for %M < MIN_INT this would be an infinite loop.
+; In these cases, the {%Start,+,-1} <nusw> predicate would be false, as the
+; final value of the expression {%Start,+,-1} expression (%M - 1) would not be
+; representable as an i16.
+
+; There is also a limit case here where the value of %M is MIN_INT. In this case
+; we still have an infinite loop, since icmp sge %x, MIN_INT will always return
+; true.
+
+; CHECK: Classifying expressions for: @test2
+
+; CHECK: %i.0.ext = sext i16 %i.0 to i32
+; CHECK-NEXT: --> (sext i16 {%Start,+,-1}<%bb3> to i32)
+; CHECK: Loop %bb3: Unpredictable backedge-taken count.
+; CHECK-NEXT: Loop %bb3: Unpredictable max backedge-taken count.
+; CHECK-NEXT: Loop %bb3: Predicated backedge-taken count is (2 + (sext i16 %Start to i32) + ((-2 + (-1 * (sext i16 %Start to i32))) smax (-1 + (-1 * %M))))
+; CHECK-NEXT: Predicates:
+; CHECK-NEXT: {%Start,+,-1}<%bb3> Added Flags: <nssw>
+
+define void @test2(i32 %N, i32 %M, i16 %Start) {
+entry:
+ br label %bb3
+
+bb: ; preds = %bb3
+ %tmp = getelementptr [1000 x i32], [1000 x i32]* @A, i32 0, i16 %i.0 ; <i32*> [#uses=1]
+ store i32 123, i32* %tmp
+ %tmp2 = sub i16 %i.0, 1 ; <i32> [#uses=1]
+ br label %bb3
+
+bb3: ; preds = %bb, %entry
+ %i.0 = phi i16 [ %Start, %entry ], [ %tmp2, %bb ] ; <i32> [#uses=3]
+ %i.0.ext = sext i16 %i.0 to i32
+ %tmp3 = icmp sge i32 %i.0.ext, %M ; <i1> [#uses=1]
+ br i1 %tmp3, label %bb, label %bb5
+
+bb5: ; preds = %bb3
+ br label %return
+
+return: ; preds = %bb5
+ ret void
+}
+
diff --git a/test/Analysis/ScalarEvolution/returned.ll b/test/Analysis/ScalarEvolution/returned.ll
new file mode 100644
index 0000000000000..4c07cd1346657
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/returned.ll
@@ -0,0 +1,16 @@
+; RUN: opt < %s -S -analyze -scalar-evolution | 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"
+
+define i8* @foo(i32 %no, i8* nocapture %d) nounwind {
+entry:
+ %v = call i8* @func1(i8* %d)
+ %w = getelementptr i8, i8* %v, i64 5
+ ret i8* %w
+}
+
+; CHECK-LABEL: Classifying expressions for: @foo
+; CHECK: %w = getelementptr i8, i8* %v, i64 5
+; CHECK-NEXT: (5 + %d)
+
+declare i8* @func1(i8* returned) nounwind argmemonly
+
diff --git a/test/Analysis/ScalarEvolution/scev-aa.ll b/test/Analysis/ScalarEvolution/scev-aa.ll
index 47a84d57c3b3c..682bd2134afc7 100644
--- a/test/Analysis/ScalarEvolution/scev-aa.ll
+++ b/test/Analysis/ScalarEvolution/scev-aa.ll
@@ -1,5 +1,7 @@
; RUN: opt -disable-output < %s -disable-basicaa -scev-aa -aa-eval -print-all-alias-modref-info \
; RUN: 2>&1 | FileCheck %s
+; RUN: opt -disable-output < %s -aa-pipeline=scev-aa -passes=aa-eval -print-all-alias-modref-info \
+; RUN: 2>&1 | FileCheck %s
; At the time of this writing, -basicaa misses the example of the form
; A[i+(j+1)] != A[i+j], which can arise from multi-dimensional array references,
diff --git a/test/Analysis/ScalarEvolution/scev-canonical-mode.ll b/test/Analysis/ScalarEvolution/scev-canonical-mode.ll
new file mode 100644
index 0000000000000..0aa7ff08f926b
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/scev-canonical-mode.ll
@@ -0,0 +1,32 @@
+; PR26529: Check the assumption of IndVarSimplify to do SCEV expansion in literal mode
+; instead of CanonicalMode is properly maintained in SCEVExpander::expand.
+; RUN: opt -indvars < %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: norecurse nounwind uwtable
+define void @ehF() #0 {
+entry:
+ br i1 undef, label %if.then.i, label %hup.exit
+
+if.then.i: ; preds = %entry
+ br i1 undef, label %for.body.lr.ph.i, label %hup.exit
+
+for.body.lr.ph.i: ; preds = %if.then.i
+ br label %for.body.i
+
+for.body.i: ; preds = %for.body.i, %for.body.lr.ph.i
+ %i.03.i = phi i32 [ 0, %for.body.lr.ph.i ], [ %inc.i, %for.body.i ]
+ %k.02.i = phi i32 [ 1, %for.body.lr.ph.i ], [ %inc5.i, %for.body.i ]
+ %inc.i = add nsw i32 %i.03.i, 1
+ %idxprom.i = sext i32 %i.03.i to i64
+ %idxprom2.i = sext i32 %k.02.i to i64
+ %inc5.i = add nsw i32 %k.02.i, 1
+ br i1 false, label %for.body.i, label %hup.exit
+
+hup.exit: ; preds = %for.body.i, %if.then.i, %entry
+ ret void
+}
+
+attributes #0 = { norecurse nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
diff --git a/test/Analysis/ScalarEvolution/scev-dispositions.ll b/test/Analysis/ScalarEvolution/scev-dispositions.ll
new file mode 100644
index 0000000000000..4e382a93cda95
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/scev-dispositions.ll
@@ -0,0 +1,73 @@
+; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s
+
+define void @single_loop(i32* %buf, i32 %start) {
+; CHECK-LABEL: Classifying expressions for: @single_loop
+ entry:
+ %val = add i32 %start, 400
+ br label %loop
+
+ loop:
+ %counter = phi i32 [ 0, %entry ], [ %counter.inc, %loop ]
+ %idx = phi i32 [ %start, %entry ], [ %idx.inc, %loop ]
+
+; CHECK: %counter = phi i32 [ 0, %entry ], [ %counter.inc, %loop ]
+; CHECK-NEXT: --> {{.*}} LoopDispositions: { %loop: Computable }
+; CHECK: %idx = phi i32 [ %start, %entry ], [ %idx.inc, %loop ]
+; CHECK-NEXT: --> {{.*}} LoopDispositions: { %loop: Computable }
+; CHECK: %val2 = add i32 %start, 400
+; CHECK-NEXT: --> {{.*}} LoopDispositions: { %loop: Invariant }
+; CHECK: %idx.inc = add nsw i32 %idx, 1
+; CHECK-NEXT: --> {{.*}} LoopDispositions: { %loop: Computable }
+; CHECK: %val3 = load volatile i32, i32* %buf
+; CHECK-NEXT: --> {{.*}} LoopDispositions: { %loop: Variant }
+
+ %val2 = add i32 %start, 400
+ %idx.inc = add nsw i32 %idx, 1
+ %idx.inc.sext = sext i32 %idx.inc to i64
+ %condition = icmp eq i32 %counter, 1
+ %counter.inc = add i32 %counter, 1
+ %val3 = load volatile i32, i32* %buf
+ br i1 %condition, label %exit, label %loop
+
+ exit:
+ ret void
+}
+
+
+define void @nested_loop(double* %p, i64 %m) {
+; CHECK-LABEL: Classifying expressions for: @nested_loop
+
+; CHECK: %j = phi i64 [ 0, %entry ], [ %j.next, %outer.latch ]
+; CHECK-NEXT: --> {{.*}} LoopDispositions: { %outer.loop: Computable, %bb: Invariant }
+; CHECK: %i = phi i64 [ 0, %outer.loop ], [ %i.next, %bb ]
+; CHECK-NEXT: --> {{.*}} LoopDispositions: { %bb: Computable, %outer.loop: Variant }
+; CHECK: %j.add = add i64 %j, 100
+; CHECK-NEXT: --> {{.*}} LoopDispositions: { %bb: Invariant, %outer.loop: Computable }
+; CHECK: %i.next = add i64 %i, 1
+; CHECK-NEXT: --> {{.*}} LoopDispositions: { %bb: Computable, %outer.loop: Variant }
+; CHECK: %j.next = add i64 %j, 91
+; CHECK-NEXT: --> {{.*}} LoopDispositions: { %outer.loop: Computable, %bb: Invariant }
+
+entry:
+ %k = icmp sgt i64 %m, 0
+ br i1 %k, label %outer.loop, label %return
+
+outer.loop:
+ %j = phi i64 [ 0, %entry ], [ %j.next, %outer.latch ]
+ br label %bb
+
+bb:
+ %i = phi i64 [ 0, %outer.loop ], [ %i.next, %bb ]
+ %j.add = add i64 %j, 100
+ %i.next = add i64 %i, 1
+ %exitcond = icmp eq i64 %i.next, 91
+ br i1 %exitcond, label %outer.latch, label %bb
+
+outer.latch:
+ %j.next = add i64 %j, 91
+ %h = icmp eq i64 %j.next, %m
+ br i1 %h, label %return, label %outer.loop
+
+return:
+ ret void
+}
diff --git a/test/Analysis/ScalarEvolution/scev-expander-existing-value.ll b/test/Analysis/ScalarEvolution/scev-expander-existing-value.ll
new file mode 100644
index 0000000000000..0c1d6766869d3
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/scev-expander-existing-value.ll
@@ -0,0 +1,38 @@
+; RUN: opt < %s -loop-vectorize -force-vector-width=4 -verify-scev-maps -S |FileCheck %s
+
+; SCEV expansion uses existing value when the SCEV has no AddRec expr.
+; CHECK: select
+; CHECK-NOT: select
+
+@a = common global [1000 x i16] zeroinitializer, align 16
+
+define i32 @foo(i32 %x, i32 %y) {
+entry:
+ %cmp = icmp slt i32 %x, %y
+ %cond = select i1 %cmp, i32 %x, i32 %y
+ %cmp1.10 = icmp sgt i32 %cond, 0
+ br i1 %cmp1.10, label %for.body.lr.ph, label %for.end
+
+for.body.lr.ph: ; preds = %entry
+ %tmp = sext i32 %cond to i64
+ 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 ]
+ %total.011 = phi i32 [ 0, %for.body.lr.ph ], [ %add, %for.body ]
+ %arrayidx = getelementptr inbounds [1000 x i16], [1000 x i16]* @a, i64 0, i64 %indvars.iv
+ %tmp1 = load i16, i16* %arrayidx, align 2
+ %conv = sext i16 %tmp1 to i32
+ %add = add nsw i32 %conv, %total.011
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %cmp1 = icmp slt i64 %indvars.iv.next, %tmp
+ br i1 %cmp1, label %for.body, label %for.end.loopexit
+
+for.end.loopexit: ; preds = %for.body
+ %add.lcssa = phi i32 [ %add, %for.body ]
+ br label %for.end
+
+for.end: ; preds = %for.end.loopexit, %entry
+ %total.0.lcssa = phi i32 [ 0, %entry ], [ %add.lcssa, %for.end.loopexit ]
+ ret i32 %total.0.lcssa
+}
diff --git a/test/Analysis/ScalarEvolution/sext-to-zext.ll b/test/Analysis/ScalarEvolution/sext-to-zext.ll
new file mode 100644
index 0000000000000..ca9c6de0d50d5
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/sext-to-zext.ll
@@ -0,0 +1,23 @@
+; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s
+
+define void @f(i1 %c) {
+; CHECK-LABEL: Classifying expressions for: @f
+entry:
+ %start = select i1 %c, i32 100, i32 0
+ %step = select i1 %c, i32 -1, i32 1
+ br label %loop
+
+loop:
+ %iv = phi i32 [ %start, %entry ], [ %iv.dec, %loop ]
+ %iv.tc = phi i32 [ 0, %entry ], [ %iv.tc.inc, %loop ]
+ %iv.tc.inc = add i32 %iv.tc, 1
+ %iv.dec = add nsw i32 %iv, %step
+ %iv.sext = sext i32 %iv to i64
+; CHECK: %iv.sext = sext i32 %iv to i64
+; CHECK-NEXT: --> {(sext i32 %start to i64),+,(sext i32 %step to i64)}<nsw><%loop>
+ %be = icmp ne i32 %iv.tc.inc, 100
+ br i1 %be, label %loop, label %leave
+
+leave:
+ ret void
+}
diff --git a/test/Analysis/ScalarEvolution/trip-count.ll b/test/Analysis/ScalarEvolution/trip-count.ll
index 89750810d1b72..d21ace9f25016 100644
--- a/test/Analysis/ScalarEvolution/trip-count.ll
+++ b/test/Analysis/ScalarEvolution/trip-count.ll
@@ -89,3 +89,25 @@ for.inc.1: ; preds = %for.body.1, %for.in
; Function Attrs: nounwind
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) #0
+
+declare void @may_exit() nounwind
+
+define void @pr28012(i32 %n) {
+; CHECK-LABEL: Classifying expressions for: @pr28012
+; CHECK: Loop %loop: backedge-taken count is -1431655751
+; CHECK: Loop %loop: max backedge-taken count is -1431655751
+; CHECK: Loop %loop: Predicated backedge-taken count is -1431655751
+
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add nsw i32 %iv, 3
+ call void @may_exit()
+ %becond = icmp ne i32 %iv.inc, 46
+ br i1 %becond, label %loop, label %leave
+
+leave:
+ ret void
+}
diff --git a/test/Analysis/ScalarEvolution/trip-count13.ll b/test/Analysis/ScalarEvolution/trip-count13.ll
new file mode 100644
index 0000000000000..37ef2fd500a0e
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/trip-count13.ll
@@ -0,0 +1,81 @@
+; RUN: opt -S -analyze -scalar-evolution < %s | FileCheck %s
+
+define void @u_0(i8 %rhs) {
+; E.g.: %rhs = 255, %start = 99, backedge taken 156 times
+entry:
+ %start = add i8 %rhs, 100
+ br label %loop
+
+loop:
+ %iv = phi i8 [ %start, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add nuw i8 %iv, 1 ;; Note: this never unsigned-wraps
+ %iv.cmp = icmp ult i8 %iv, %rhs
+ br i1 %iv.cmp, label %loop, label %leave
+
+; CHECK-LABEL: Determining loop execution counts for: @u_0
+; CHECK-NEXT: Loop %loop: backedge-taken count is (-100 + (-1 * %rhs) + ((100 + %rhs) umax %rhs))
+; CHECK-NEXT: Loop %loop: max backedge-taken count is -1
+
+leave:
+ ret void
+}
+
+define void @u_1(i8 %start) {
+entry:
+; E.g.: %start = 99, %rhs = 255, backedge taken 156 times
+ %rhs = add i8 %start, -100
+ br label %loop
+
+loop:
+ %iv = phi i8 [ %start, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add nuw i8 %iv, 1 ;; Note: this never unsigned-wraps
+ %iv.cmp = icmp ult i8 %iv, %rhs
+ br i1 %iv.cmp, label %loop, label %leave
+
+; CHECK-LABEL: Determining loop execution counts for: @u_1
+; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %start) + ((-100 + %start) umax %start))
+; CHECK-NEXT: Loop %loop: max backedge-taken count is -1
+
+leave:
+ ret void
+}
+
+define void @s_0(i8 %rhs) {
+entry:
+; E.g.: %rhs = 127, %start = -29, backedge taken 156 times
+ %start = add i8 %rhs, 100
+ br label %loop
+
+loop:
+ %iv = phi i8 [ %start, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add nsw i8 %iv, 1 ;; Note: this never signed-wraps
+ %iv.cmp = icmp slt i8 %iv, %rhs
+ br i1 %iv.cmp, label %loop, label %leave
+
+; CHECK-LABEL: Determining loop execution counts for: @s_0
+; CHECK-NEXT: Loop %loop: backedge-taken count is (-100 + (-1 * %rhs) + ((100 + %rhs) smax %rhs))
+; CHECK-NEXT: Loop %loop: max backedge-taken count is -1
+
+leave:
+ ret void
+}
+
+define void @s_1(i8 %start) {
+entry:
+; E.g.: start = -29, %rhs = 127, %backedge taken 156 times
+ %rhs = add i8 %start, -100
+ br label %loop
+
+loop:
+ %iv = phi i8 [ %start, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add nsw i8 %iv, 1
+ %iv.cmp = icmp slt i8 %iv, %rhs
+ br i1 %iv.cmp, label %loop, label %leave
+
+; CHECK-LABEL: Determining loop execution counts for: @s_1
+; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %start) + ((-100 + %start) smax %start))
+; CHECK-NEXT: Loop %loop: max backedge-taken count is -1
+
+leave:
+ ret void
+}
diff --git a/test/Analysis/ScopedNoAliasAA/basic.ll b/test/Analysis/ScopedNoAliasAA/basic.ll
index 26258341cc14e..69e088e89763e 100644
--- a/test/Analysis/ScopedNoAliasAA/basic.ll
+++ b/test/Analysis/ScopedNoAliasAA/basic.ll
@@ -1,13 +1,14 @@
; RUN: opt < %s -basicaa -scoped-noalias -aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=basic-aa,scoped-noalias-aa -passes=aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define void @foo1(float* nocapture %a, float* nocapture readonly %c) #0 {
entry:
; CHECK-LABEL: Function: foo1
- %0 = load float, float* %c, align 4, !alias.scope !1
+ %0 = load float, float* %c, align 4, !alias.scope !2
%arrayidx.i = getelementptr inbounds float, float* %a, i64 5
- store float %0, float* %arrayidx.i, align 4, !noalias !1
+ store float %0, float* %arrayidx.i, align 4, !noalias !2
%1 = load float, float* %c, align 4
%arrayidx = getelementptr inbounds float, float* %a, i64 7
store float %1, float* %arrayidx, align 4
@@ -24,4 +25,4 @@ attributes #0 = { nounwind uwtable }
!0 = !{!0, !"some domain"}
!1 = !{!1, !0, !"some scope"}
-
+!2 = !{!1}
diff --git a/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll b/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll
index fe2fdd74b411d..ed091466165e0 100644
--- a/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll
+++ b/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll
@@ -43,13 +43,13 @@ define void @test1_no(i32* %p) nounwind {
; This is unusual, since the function is memcpy, but as above, this
; isn't necessarily invalid.
-; CHECK: define void @test2_yes(i8* nocapture %p, i8* nocapture %q, i64 %n) #0 {
+; CHECK: define void @test2_yes(i8* nocapture %p, i8* nocapture %q, i64 %n) #4 {
define void @test2_yes(i8* %p, i8* %q, i64 %n) nounwind {
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %p, i8* %q, i64 %n, i32 1, i1 false), !tbaa !1
ret void
}
-; CHECK: define void @test2_no(i8* nocapture %p, i8* nocapture readonly %q, i64 %n) #1 {
+; CHECK: define void @test2_no(i8* nocapture %p, i8* nocapture readonly %q, i64 %n) #3 {
define void @test2_no(i8* %p, i8* %q, i64 %n) nounwind {
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %p, i8* %q, i64 %n, i32 1, i1 false), !tbaa !2
ret void
@@ -76,7 +76,8 @@ declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i32, i1) nounwind
; CHECK: attributes #1 = { norecurse nounwind }
; CHECK: attributes #2 = { nounwind readonly }
; CHECK: attributes #3 = { nounwind }
-; CHECK: attributes #4 = { argmemonly nounwind }
+; CHECK: attributes #4 = { nounwind readnone }
+; CHECK: attributes #5 = { argmemonly nounwind }
; Root note.
!0 = !{ }
diff --git a/test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll b/test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll
index aa91020f12d67..54d57133b99c6 100644
--- a/test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll
+++ b/test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll
@@ -1,4 +1,5 @@
; RUN: opt < %s -tbaa -basicaa -aa-eval -evaluate-aa-metadata -print-no-aliases -print-may-aliases -disable-output 2>&1 | FileCheck %s
+; RUN: opt < %s -aa-pipeline=type-based-aa,basic-aa -passes=aa-eval -evaluate-aa-metadata -print-no-aliases -print-may-aliases -disable-output 2>&1 | FileCheck %s
; Generated with "clang -cc1 -disable-llvm-optzns -O1 -emit-llvm"
; #include <new>
diff --git a/test/Analysis/ValueTracking/deref-bitcast-of-gep.ll b/test/Analysis/ValueTracking/deref-bitcast-of-gep.ll
new file mode 100644
index 0000000000000..38a8da8c09823
--- /dev/null
+++ b/test/Analysis/ValueTracking/deref-bitcast-of-gep.ll
@@ -0,0 +1,82 @@
+; RUN: opt -S -licm < %s | FileCheck %s
+
+; Note: the !invariant.load is there just solely to let us call @use()
+; to add a fake use, and still have the aliasing work out. The call
+; to @use(0) is just to provide a may-unwind exit out of the loop, so
+; that LICM cannot hoist out the load simply because it is guaranteed
+; to execute.
+
+declare void @use(i32)
+
+define void @f_0(i8* align 4 dereferenceable(1024) %ptr) {
+; CHECK-LABEL: @f_0(
+; CHECK: entry:
+; CHECK: %val = load i32, i32* %ptr.i32
+; CHECK: br label %loop
+; CHECK: loop:
+; CHECK: call void @use(i32 0)
+; CHECK-NEXT: call void @use(i32 %val)
+
+
+entry:
+ %ptr.gep = getelementptr i8, i8* %ptr, i32 32
+ %ptr.i32 = bitcast i8* %ptr.gep to i32*
+ br label %loop
+
+loop:
+ call void @use(i32 0)
+ %val = load i32, i32* %ptr.i32, !invariant.load !{}
+ call void @use(i32 %val)
+ br label %loop
+}
+
+define void @f_1(i8* align 4 dereferenceable_or_null(1024) %ptr) {
+; CHECK-LABEL: @f_1(
+entry:
+ %ptr.gep = getelementptr i8, i8* %ptr, i32 32
+ %ptr.i32 = bitcast i8* %ptr.gep to i32*
+ %ptr_is_null = icmp eq i8* %ptr, null
+ br i1 %ptr_is_null, label %leave, label %loop
+
+; CHECK: loop.preheader:
+; CHECK: %val = load i32, i32* %ptr.i32
+; CHECK: br label %loop
+; CHECK: loop:
+; CHECK: call void @use(i32 0)
+; CHECK-NEXT: call void @use(i32 %val)
+
+loop:
+ call void @use(i32 0)
+ %val = load i32, i32* %ptr.i32, !invariant.load !{}
+ call void @use(i32 %val)
+ br label %loop
+
+leave:
+ ret void
+}
+
+define void @f_2(i8* align 4 dereferenceable_or_null(1024) %ptr) {
+; CHECK-LABEL: @f_2(
+; CHECK-NOT: load
+; CHECK: call void @use(i32 0)
+; CHECK-NEXT: %val = load i32, i32* %ptr.i32, !invariant.load !0
+; CHECK-NEXT: call void @use(i32 %val)
+
+entry:
+ ;; Can't hoist, since the alignment does not work out -- (<4 byte
+ ;; aligned> + 30) is not necessarily 4 byte aligned.
+
+ %ptr.gep = getelementptr i8, i8* %ptr, i32 30
+ %ptr.i32 = bitcast i8* %ptr.gep to i32*
+ %ptr_is_null = icmp eq i8* %ptr, null
+ br i1 %ptr_is_null, label %leave, label %loop
+
+loop:
+ call void @use(i32 0)
+ %val = load i32, i32* %ptr.i32, !invariant.load !{}
+ call void @use(i32 %val)
+ br label %loop
+
+leave:
+ ret void
+}
diff --git a/test/Analysis/ValueTracking/dom-cond.ll b/test/Analysis/ValueTracking/dom-cond.ll
deleted file mode 100644
index c0cafdd0ade08..0000000000000
--- a/test/Analysis/ValueTracking/dom-cond.ll
+++ /dev/null
@@ -1,18 +0,0 @@
-; RUN: opt < %s -instcombine -value-tracking-dom-conditions -S | FileCheck %s
-
-define i32 @dom_cond(i32 %a, i32 %b) {
-; CHECK-LABEL: @dom_cond(
-entry:
- %v = add i32 %a, %b
- %cond = icmp ule i32 %v, 7
- br i1 %cond, label %then, label %exit
-
-then:
- %v2 = add i32 %v, 8
-; CHECK: or i32 %v, 8
- br label %exit
-
-exit:
- %v3 = phi i32 [ %v, %entry ], [ %v2, %then ]
- ret i32 %v3
-}
diff --git a/test/Analysis/ValueTracking/known-bits-from-range-md.ll b/test/Analysis/ValueTracking/known-bits-from-range-md.ll
index e1de089b3501c..3bd8c287af963 100644
--- a/test/Analysis/ValueTracking/known-bits-from-range-md.ll
+++ b/test/Analysis/ValueTracking/known-bits-from-range-md.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -instsimplify < %s | FileCheck %s
+; RUN: opt -S -instsimplify -instcombine < %s | FileCheck %s
define i1 @test0(i8* %ptr) {
; CHECK-LABEL: @test0(
@@ -23,10 +23,10 @@ define i1 @test1(i8* %ptr) {
define i1 @test2(i8* %ptr) {
; CHECK-LABEL: @test2(
entry:
-; CHECK: load
-; CHECK: and
-; CHECK: icmp eq
-; CHECK: ret
+; CHECK: %val = load i8
+; CHECK: %and = and i8 %val
+; CHECK: %is.eq = icmp ne i8 %and, 0
+; CHECK: ret i1 %is.eq
%val = load i8, i8* %ptr, !range !{i8 64, i8 129}
%and = and i8 %val, 64
%is.eq = icmp eq i8 %and, 64
diff --git a/test/Analysis/ValueTracking/memory-dereferenceable.ll b/test/Analysis/ValueTracking/memory-dereferenceable.ll
index 5b45172f695e1..29c31b95b188e 100644
--- a/test/Analysis/ValueTracking/memory-dereferenceable.ll
+++ b/test/Analysis/ValueTracking/memory-dereferenceable.ll
@@ -3,7 +3,7 @@
; Uses the print-deref (+ analyze to print) pass to run
; isDereferenceablePointer() on many load instruction operands
-target datalayout = "e"
+target datalayout = "e-i32:32:64"
%TypeOpaque = type opaque
@@ -43,7 +43,8 @@ entry:
%load4 = load i32, i32 addrspace(1)* %relocate
; CHECK-NOT: %nparam
- %nparam = getelementptr i32, i32 addrspace(1)* %dparam, i32 5
+ %dpa = call i32 addrspace(1)* @func1(i32 addrspace(1)* %dparam)
+ %nparam = getelementptr i32, i32 addrspace(1)* %dpa, i32 5
%load5 = load i32, i32 addrspace(1)* %nparam
; Load from a non-dereferenceable load
@@ -133,6 +134,12 @@ entry:
%load26 = load i32, i32* %d4_unaligned_load, align 16
%load27 = load i32, i32* %d4_aligned_load, align 16
+ ; Alloca with no explicit alignment is aligned to preferred alignment of
+ ; the type (specified by datalayout string).
+; CHECK: %alloca.noalign{{.*}}(aligned)
+ %alloca.noalign = alloca i32
+ %load28 = load i32, i32* %alloca.noalign, align 8
+
ret void
}
@@ -156,6 +163,8 @@ if.end:
declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32)
+declare i32 addrspace(1)* @func1(i32 addrspace(1)* returned) nounwind argmemonly
+
!0 = !{i64 4}
!1 = !{i64 2}
!2 = !{}
diff --git a/test/Analysis/ValueTracking/pr24866.ll b/test/Analysis/ValueTracking/pr24866.ll
deleted file mode 100644
index b146b4ac05643..0000000000000
--- a/test/Analysis/ValueTracking/pr24866.ll
+++ /dev/null
@@ -1,44 +0,0 @@
-; RUN: opt -S %s -value-tracking-dom-conditions -licm -load-combine | FileCheck %s
-; In pr24866.ll, we saw a crash when accessing a nullptr returned when
-; asking for a dominator tree Node. This reproducer is really fragile,
-; but it's currently the best we have.
-
-%struct.c_derived_tbl.2.5.8.11.14.17.23.38.59.80.92.98.104.107.155.183 = type { [256 x i32], [256 x i8] }
-
-
-; Function Attrs: nounwind uwtable
-define void @encode_one_blockX2(%struct.c_derived_tbl.2.5.8.11.14.17.23.38.59.80.92.98.104.107.155.183* nocapture readonly %actbl) #0 {
-; CHECK-LABEL: @encode_one_blockX2
-entry:
- br i1 false, label %L_KLOOP_01, label %L_KLOOP.preheader
-
-L_KLOOP_01: ; preds = %while.end, %entry
- br label %L_KLOOP.preheader
-
-L_KLOOP_08: ; preds = %while.end
- br label %L_KLOOP.preheader
-
-L_KLOOP.preheader: ; preds = %L_KLOOP_08, %L_KLOOP_01, %entry
- %r.2.ph = phi i32 [ undef, %L_KLOOP_08 ], [ 0, %entry ], [ undef, %L_KLOOP_01 ]
- br label %L_KLOOP
-
-L_KLOOP: ; preds = %while.end, %L_KLOOP.preheader
- %r.2 = phi i32 [ 0, %while.end ], [ %r.2.ph, %L_KLOOP.preheader ]
- br i1 true, label %while.body, label %while.end
-
-while.body: ; preds = %while.body, %L_KLOOP
- br label %while.body
-
-while.end: ; preds = %L_KLOOP
- %shl105 = shl i32 %r.2, 4
- %add106 = add nsw i32 %shl105, undef
- %idxprom107 = sext i32 %add106 to i64
- %arrayidx108 = getelementptr inbounds %struct.c_derived_tbl.2.5.8.11.14.17.23.38.59.80.92.98.104.107.155.183, %struct.c_derived_tbl.2.5.8.11.14.17.23.38.59.80.92.98.104.107.155.183* %actbl, i64 0, i32 0, i64 %idxprom107
- %0 = load i32, i32* %arrayidx108, align 4
- %arrayidx110 = getelementptr inbounds %struct.c_derived_tbl.2.5.8.11.14.17.23.38.59.80.92.98.104.107.155.183, %struct.c_derived_tbl.2.5.8.11.14.17.23.38.59.80.92.98.104.107.155.183* %actbl, i64 0, i32 1, i64 %idxprom107
- %1 = load i8, i8* %arrayidx110, align 1
- indirectbr i8* undef, [label %L_KLOOP_DONE, label %L_KLOOP_01, label %L_KLOOP_08, label %L_KLOOP]
-
-L_KLOOP_DONE: ; preds = %while.end
- ret void
-}
diff --git a/test/Analysis/alias-analysis-uses.ll b/test/Analysis/alias-analysis-uses.ll
new file mode 100644
index 0000000000000..4163ec25584c6
--- /dev/null
+++ b/test/Analysis/alias-analysis-uses.ll
@@ -0,0 +1,10 @@
+; RUN: opt -debug-pass=Executions -globals-aa -functionattrs -disable-output < %s 2>&1 | FileCheck %s
+
+; CHECK: Executing Pass 'Globals Alias Analysis'
+; CHECK-NOT: Freeing Pass 'Globals Alias Analysis'
+; CHECK: Executing Pass 'Deduce function attributes'
+; CHECK: Freeing Pass 'Globals Alias Analysis'
+
+define void @test(i8* %p) {
+ ret void
+}