xref: /llvm-project/llvm/test/Transforms/MemCpyOpt/stack-move.ll (revision 29441e4f5fa5f5c7709f7cf180815ba97f611297)
139321564Skhei4; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
290ecb9d5Skhei4; RUN: opt < %s -passes=memcpyopt -verify-memoryssa -S | FileCheck %s
339321564Skhei4
439321564Skhei4%struct.Foo = type { i32, i32, i32 }
539321564Skhei4
639321564Skhei4declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg)
739321564Skhei4declare void @llvm.memcpy.p1.p0.i64(ptr addrspace(1) noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg)
839321564Skhei4declare void @llvm.memcpy.p2.p1.i64(ptr addrspace(2) noalias nocapture writeonly, ptr addrspace(1) noalias nocapture readonly, i64, i1 immarg)
939321564Skhei4declare void @llvm.memmove.p0.p0.i64(ptr nocapture writeonly, ptr nocapture readonly, i64, i1 immarg)
10e0911b98Skhei4declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg)
1139321564Skhei4
1239321564Skhei4declare void @llvm.lifetime.start.p0(i64, ptr nocapture)
1339321564Skhei4declare void @llvm.lifetime.end.p0(i64, ptr nocapture)
1439321564Skhei4declare void @llvm.lifetime.start.p1(i64, ptr addrspace(1) nocapture)
1539321564Skhei4declare void @llvm.lifetime.end.p1(i64, ptr addrspace(1) nocapture)
1639321564Skhei4declare void @llvm.lifetime.start.p2(i64, ptr addrspace(2) nocapture)
1739321564Skhei4declare void @llvm.lifetime.end.p2(i64, ptr addrspace(2) nocapture)
1839321564Skhei4
1939321564Skhei4declare i32 @use_nocapture(ptr nocapture)
2039321564Skhei4declare i32 @use_maycapture(ptr noundef)
2139321564Skhei4declare i32 @use_readonly(ptr readonly)
2239321564Skhei4declare i32 @use_writeonly(ptr noundef) memory(write)
2339321564Skhei4
2439321564Skhei4define void @basic_memcpy() {
2539321564Skhei4; CHECK-LABEL: define void @basic_memcpy() {
2639321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
2739321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
28*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
29*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
3039321564Skhei4; CHECK-NEXT:    ret void
3139321564Skhei4;
3239321564Skhei4  %src = alloca %struct.Foo, align 4
3339321564Skhei4  %dest = alloca %struct.Foo, align 4
3439321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
3539321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
3639321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
3739321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
3839321564Skhei4
3939321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
4039321564Skhei4
4139321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
4239321564Skhei4
4339321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
4439321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
4539321564Skhei4  ret void
4639321564Skhei4}
4739321564Skhei4
482a207128SKohei Asanodefine i32 @use_not_dominated_by_src_alloca() {
492a207128SKohei Asano; CHECK-LABEL: define i32 @use_not_dominated_by_src_alloca() {
502a207128SKohei Asano; CHECK-NEXT:    [[SRC:%.*]] = alloca i8, align 4
512a207128SKohei Asano; CHECK-NEXT:    [[DEST_GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 -1
522a207128SKohei Asano; CHECK-NEXT:    [[DEST_USE:%.*]] = load i8, ptr [[DEST_GEP]], align 1
532a207128SKohei Asano; CHECK-NEXT:    ret i32 0
542a207128SKohei Asano;
552a207128SKohei Asano  %dest = alloca i1, align 1
562a207128SKohei Asano  ; Replacing the use of dest with src causes no domination uses.
572a207128SKohei Asano  %dest.gep = getelementptr i64, ptr %dest, i64 -1
582a207128SKohei Asano  %dest.use = load i8, ptr %dest.gep, align 1
592a207128SKohei Asano  %src = alloca i8, align 4
602a207128SKohei Asano  %src.val = load i1, ptr %src, align 4
612a207128SKohei Asano
622a207128SKohei Asano  store i1 %src.val, ptr %dest, align 1
632a207128SKohei Asano
642a207128SKohei Asano  ret i32 0
652a207128SKohei Asano}
662a207128SKohei Asano
6739321564Skhei4define void @basic_memmove() {
6839321564Skhei4; CHECK-LABEL: define void @basic_memmove() {
6939321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
7039321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
71*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
72*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
7339321564Skhei4; CHECK-NEXT:    ret void
7439321564Skhei4;
7539321564Skhei4  %src = alloca %struct.Foo, align 4
7639321564Skhei4  %dest = alloca %struct.Foo, align 4
7739321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
7839321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
7939321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
8039321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
8139321564Skhei4
8239321564Skhei4  call void @llvm.memmove.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
8339321564Skhei4
8439321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
8539321564Skhei4
8639321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
8739321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
8839321564Skhei4  ret void
8939321564Skhei4}
9039321564Skhei4
9139321564Skhei4; Tests that the optimization succeeds with a load/store pair.
9239321564Skhei4define void @load_store() {
9339321564Skhei4; CHECK-LABEL: define void @load_store() {
9439321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca i32, align 4
9539321564Skhei4; CHECK-NEXT:    store i32 42, ptr [[SRC]], align 4
96*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
97*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
9839321564Skhei4; CHECK-NEXT:    ret void
9939321564Skhei4;
10039321564Skhei4  %src = alloca i32, align 4
10139321564Skhei4  %dest = alloca i32, align 4
10239321564Skhei4  call void @llvm.lifetime.start.p0(i64 4, ptr nocapture %src)
10339321564Skhei4  call void @llvm.lifetime.start.p0(i64 4, ptr nocapture %dest)
10439321564Skhei4  store i32 42, ptr %src
10539321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
10639321564Skhei4
10739321564Skhei4  %src.val = load i32, ptr %src
10839321564Skhei4  store i32 %src.val, ptr %dest
10939321564Skhei4
11039321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
11139321564Skhei4  call void @llvm.lifetime.end.p0(i64 4, ptr nocapture %src)
11239321564Skhei4  call void @llvm.lifetime.end.p0(i64 4, ptr nocapture %dest)
11339321564Skhei4  ret void
11439321564Skhei4}
11539321564Skhei4
116689ace53SCraig Topper; Test scalable vectors.
117689ace53SCraig Topperdefine void @load_store_scalable(<vscale x 4 x i32> %x) {
118689ace53SCraig Topper; CHECK-LABEL: define void @load_store_scalable
119689ace53SCraig Topper; CHECK-SAME: (<vscale x 4 x i32> [[X:%.*]]) {
120689ace53SCraig Topper; CHECK-NEXT:    [[SRC:%.*]] = alloca <vscale x 4 x i32>, align 16
121689ace53SCraig Topper; CHECK-NEXT:    store <vscale x 4 x i32> [[X]], ptr [[SRC]], align 16
122*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
123*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
124689ace53SCraig Topper; CHECK-NEXT:    ret void
125689ace53SCraig Topper;
126689ace53SCraig Topper  %src = alloca <vscale x 4 x i32>
127689ace53SCraig Topper  %dest = alloca <vscale x 4 x i32>
128689ace53SCraig Topper  call void @llvm.lifetime.start.p0(i64 -1, ptr nocapture %src)
129689ace53SCraig Topper  call void @llvm.lifetime.start.p0(i64 -1, ptr nocapture %dest)
130689ace53SCraig Topper  store <vscale x 4 x i32> %x, ptr %src
131689ace53SCraig Topper  %1 = call i32 @use_nocapture(ptr nocapture %src)
132689ace53SCraig Topper
133689ace53SCraig Topper  %src.val = load <vscale x 4 x i32>, ptr %src
134689ace53SCraig Topper  store <vscale x 4 x i32> %src.val, ptr %dest
135689ace53SCraig Topper
136689ace53SCraig Topper  %2 = call i32 @use_nocapture(ptr nocapture %dest)
137689ace53SCraig Topper
138689ace53SCraig Topper  call void @llvm.lifetime.end.p0(i64 -1, ptr nocapture %src)
139689ace53SCraig Topper  call void @llvm.lifetime.end.p0(i64 -1, ptr nocapture %dest)
140689ace53SCraig Topper  ret void
141689ace53SCraig Topper}
142689ace53SCraig Topper
14339321564Skhei4; Tests that merging two allocas shouldn't be more poisonous, smaller aligned src is valid.
14439321564Skhei4define void @align_up() {
14539321564Skhei4; CHECK-LABEL: define void @align_up() {
146ca68a7f9Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 8
14739321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
148*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
149*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
15039321564Skhei4; CHECK-NEXT:    ret void
15139321564Skhei4;
15239321564Skhei4  %src = alloca %struct.Foo, align 4
15339321564Skhei4  %dest = alloca %struct.Foo, align 8
15439321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
15539321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
15639321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
15739321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
15839321564Skhei4
15939321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
16039321564Skhei4
16139321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
16239321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
16339321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
16439321564Skhei4  ret void
16539321564Skhei4}
16639321564Skhei4
16739321564Skhei4; Tests that we correctly remove extra lifetime intrinsics when performing the
16839321564Skhei4; optimization.
16939321564Skhei4define void @remove_extra_lifetime_intrinsics() {
17039321564Skhei4; CHECK-LABEL: define void @remove_extra_lifetime_intrinsics() {
17139321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
17239321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
173*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
174*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
175*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
17639321564Skhei4; CHECK-NEXT:    ret void
17739321564Skhei4;
17839321564Skhei4  %src = alloca %struct.Foo, align 4
17939321564Skhei4  %dest = alloca %struct.Foo, align 4
18039321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
18139321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
18239321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
18339321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
18439321564Skhei4
18539321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
18639321564Skhei4
18739321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
18839321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
18939321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
19039321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
19139321564Skhei4  %3 = call i32 @use_nocapture(ptr nocapture %dest)
19239321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
19339321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
19439321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
19539321564Skhei4  ret void
19639321564Skhei4}
19739321564Skhei4
19839321564Skhei4; Tests that we won't insert lifetime markers if they don't exist originally.
19939321564Skhei4define void @no_lifetime() {
20039321564Skhei4; CHECK-LABEL: define void @no_lifetime() {
20139321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
20239321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
203*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
204*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
205*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
20639321564Skhei4; CHECK-NEXT:    ret void
20739321564Skhei4;
20839321564Skhei4  %src = alloca %struct.Foo, align 4
20939321564Skhei4  %dest = alloca %struct.Foo, align 4
21039321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
21139321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
21239321564Skhei4
21339321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
21439321564Skhei4
21539321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
21639321564Skhei4  %3 = call i32 @use_nocapture(ptr nocapture %dest)
21739321564Skhei4  ret void
21839321564Skhei4}
21939321564Skhei4
22039321564Skhei4; Tests that aliasing src or dest but no modification desn't prevent transformations.
22139321564Skhei4define void @alias_no_mod() {
22239321564Skhei4; CHECK-LABEL: define void @alias_no_mod() {
22339321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
224ca68a7f9Skhei4; CHECK-NEXT:    [[DEST_ALIAS:%.*]] = getelementptr [[STRUCT_FOO]], ptr [[SRC]], i32 0, i32 0
22539321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
226*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
22739321564Skhei4; CHECK-NEXT:    [[SRC_ALIAS:%.*]] = getelementptr [[STRUCT_FOO]], ptr [[SRC]], i32 0, i32 0
228*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
22939321564Skhei4; CHECK-NEXT:    ret void
23039321564Skhei4;
23139321564Skhei4  %src = alloca %struct.Foo, align 4
23239321564Skhei4  %dest = alloca %struct.Foo, align 4
23339321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
23439321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
23539321564Skhei4  %dest.alias = getelementptr %struct.Foo, ptr %dest, i32 0, i32 0
23639321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
23739321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
23839321564Skhei4
23939321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
24039321564Skhei4
24139321564Skhei4  %src.alias = getelementptr %struct.Foo, ptr %src, i32 0, i32 0
24239321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
24339321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
24439321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
24539321564Skhei4  ret void
24639321564Skhei4}
24739321564Skhei4
24839321564Skhei4; Scope domain
24939321564Skhei4!0 = !{!0}
25039321564Skhei4; Scope in that domain
25139321564Skhei4!1 = !{!1, !0}
25239321564Skhei4; Scope list
25339321564Skhei4!2 = !{!1}
25439321564Skhei4
25539321564Skhei4!3 = !{!"Whatever"}
25639321564Skhei4
25739321564Skhei4; Tests that we remove scoped noalias metadata from a call.
25839321564Skhei4define void @remove_scoped_noalias() {
25939321564Skhei4; CHECK-LABEL: define void @remove_scoped_noalias() {
26039321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
26139321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
262*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]]), !alias.scope [[META0:![0-9]+]]
263*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
26439321564Skhei4; CHECK-NEXT:    ret void
26539321564Skhei4;
26639321564Skhei4  %src = alloca %struct.Foo, align 4
26739321564Skhei4  %dest = alloca %struct.Foo, align 4
26839321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
26939321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
27039321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
27139321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src), !alias.scope !2
27239321564Skhei4
27339321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
27439321564Skhei4
27539321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
27639321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest), !noalias !2
27739321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
27839321564Skhei4  ret void
27939321564Skhei4}
28039321564Skhei4
28139321564Skhei4; Tests that we remove metadata on the merged alloca.
28239321564Skhei4define void @remove_alloca_metadata() {
28339321564Skhei4; CHECK-LABEL: define void @remove_alloca_metadata() {
284ca68a7f9Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
28539321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
286*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]]), !alias.scope [[META0]]
287*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
28839321564Skhei4; CHECK-NEXT:    ret void
28939321564Skhei4;
29039321564Skhei4  %src = alloca %struct.Foo, align 4, !annotation !3
29139321564Skhei4  %dest = alloca %struct.Foo, align 4
29239321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
29339321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
29439321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
29539321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src), !alias.scope !2
29639321564Skhei4
29739321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
29839321564Skhei4
29939321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest), !noalias !2
30039321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
30139321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
30239321564Skhei4  ret void
30339321564Skhei4}
30439321564Skhei4
305d878916cSkhei4; Tests that we remove scoped noalias metadata from a call.
306d878916cSkhei4; And confirm that don't crash on noalias metadata on lifetime markers.
307d878916cSkhei4define void @noalias_on_lifetime() {
308d878916cSkhei4; CHECK-LABEL: define void @noalias_on_lifetime() {
309d878916cSkhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
310d878916cSkhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
311*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]]), !alias.scope [[META0]]
312*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
313d878916cSkhei4; CHECK-NEXT:    ret void
314d878916cSkhei4;
315d878916cSkhei4  %src = alloca %struct.Foo, align 4
316d878916cSkhei4  %dest = alloca %struct.Foo, align 4
317d878916cSkhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
318d878916cSkhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
319d878916cSkhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
320d878916cSkhei4  %1 = call i32 @use_nocapture(ptr nocapture %src), !alias.scope !2
321d878916cSkhei4
322d878916cSkhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
323d878916cSkhei4
324d878916cSkhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src), !alias.scope !2
325d878916cSkhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest), !noalias !2
326d878916cSkhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest), !noalias !2
327d878916cSkhei4  ret void
328d878916cSkhei4}
329d878916cSkhei4
33039321564Skhei4; Tests that we can merge alloca if the dest and src has only refs except lifetime intrinsics.
33139321564Skhei4define void @src_ref_dest_ref_after_copy() {
33239321564Skhei4; CHECK-LABEL: define void @src_ref_dest_ref_after_copy() {
33339321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
33439321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
335*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_readonly(ptr captures(none) [[SRC]])
336*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_readonly(ptr captures(none) [[SRC]])
33739321564Skhei4; CHECK-NEXT:    ret void
33839321564Skhei4;
33939321564Skhei4  %src = alloca %struct.Foo, align 4
34039321564Skhei4  %dest = alloca %struct.Foo, align 4
34139321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
34239321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
34339321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
34439321564Skhei4
34539321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
34639321564Skhei4
34739321564Skhei4  %1 = call i32 @use_readonly(ptr nocapture %src)
34839321564Skhei4  %2 = call i32 @use_readonly(ptr nocapture %dest)
34939321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
35039321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
35139321564Skhei4  ret void
35239321564Skhei4}
35339321564Skhei4
35439321564Skhei4; Tests that we can merge alloca if the dest and src has only mods.
35539321564Skhei4define void @src_mod_dest_mod_after_copy() {
35639321564Skhei4; CHECK-LABEL: define void @src_mod_dest_mod_after_copy() {
35739321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
35839321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
359*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_writeonly(ptr captures(none) [[SRC]])
360*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_writeonly(ptr captures(none) [[SRC]])
36139321564Skhei4; CHECK-NEXT:    ret void
36239321564Skhei4;
36339321564Skhei4  %src = alloca %struct.Foo, align 4
36439321564Skhei4  %dest = alloca %struct.Foo, align 4
36539321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
36639321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
36739321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
36839321564Skhei4
36939321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
37039321564Skhei4
37139321564Skhei4  %1 = call i32 @use_writeonly(ptr nocapture %src)
37239321564Skhei4  %2 = call i32 @use_writeonly(ptr nocapture %dest)
37339321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
37439321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
37539321564Skhei4  ret void
37639321564Skhei4}
37739321564Skhei4
3780b4f8c9fSkhei4define void @avoid_memory_use_last_user_crash() {
3790b4f8c9fSkhei4; CHECK-LABEL: define void @avoid_memory_use_last_user_crash() {
3800b4f8c9fSkhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
3810b4f8c9fSkhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
382ca68a7f9Skhei4; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[SRC]], align 4
3830b4f8c9fSkhei4; CHECK-NEXT:    ret void
3840b4f8c9fSkhei4;
3850b4f8c9fSkhei4  %src = alloca %struct.Foo, align 4
3860b4f8c9fSkhei4  %dest = alloca %struct.Foo, align 4
3870b4f8c9fSkhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
3880b4f8c9fSkhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
3890b4f8c9fSkhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
3900b4f8c9fSkhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
3910b4f8c9fSkhei4  %v = load i32, ptr %dest
3920b4f8c9fSkhei4  ret void
3930b4f8c9fSkhei4}
3940b4f8c9fSkhei4
395bdc9a6b1Skhei4; For multi-bb patch, we will insert it for next immediate post dominator block.
396bdc9a6b1Skhei4define void @terminator_lastuse() personality i32 0 {
397bdc9a6b1Skhei4; CHECK-LABEL: define void @terminator_lastuse() personality i32 0 {
398bdc9a6b1Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
399bdc9a6b1Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
400*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
401ca68a7f9Skhei4; CHECK-NEXT:    [[RV:%.*]] = invoke i32 @use_nocapture(ptr [[SRC]])
402bdc9a6b1Skhei4; CHECK-NEXT:            to label [[SUC:%.*]] unwind label [[UNW:%.*]]
403bdc9a6b1Skhei4; CHECK:       unw:
404bdc9a6b1Skhei4; CHECK-NEXT:    [[LP:%.*]] = landingpad i32
405bdc9a6b1Skhei4; CHECK-NEXT:            cleanup
406bdc9a6b1Skhei4; CHECK-NEXT:    resume i32 0
407bdc9a6b1Skhei4; CHECK:       suc:
408bdc9a6b1Skhei4; CHECK-NEXT:    ret void
409bdc9a6b1Skhei4;
410bdc9a6b1Skhei4  %src = alloca %struct.Foo, align 4
411bdc9a6b1Skhei4  %dest = alloca %struct.Foo, align 4
412bdc9a6b1Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
413bdc9a6b1Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
414bdc9a6b1Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
415bdc9a6b1Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
416bdc9a6b1Skhei4
417bdc9a6b1Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
418bdc9a6b1Skhei4
419bdc9a6b1Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr %src)
420bdc9a6b1Skhei4  %rv = invoke i32 @use_nocapture(ptr %dest)
421bdc9a6b1Skhei4  to label %suc unwind label %unw
422bdc9a6b1Skhei4unw:
423bdc9a6b1Skhei4  %lp = landingpad i32 cleanup
424bdc9a6b1Skhei4  resume i32 0
425bdc9a6b1Skhei4suc:
426bdc9a6b1Skhei4  ret void
427bdc9a6b1Skhei4}
428bdc9a6b1Skhei4
429a92e1971Skhei4define void @multi_bb_memcpy(i1 %b) {
430a92e1971Skhei4; CHECK-LABEL: define void @multi_bb_memcpy
431a92e1971Skhei4; CHECK-SAME: (i1 [[B:%.*]]) {
432a92e1971Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca i32, align 4
433a92e1971Skhei4; CHECK-NEXT:    store i32 42, ptr [[SRC]], align 4
434*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
435a92e1971Skhei4; CHECK-NEXT:    br label [[BB0:%.*]]
436a92e1971Skhei4; CHECK:       bb0:
437a92e1971Skhei4; CHECK-NEXT:    br label [[BB1:%.*]]
438a92e1971Skhei4; CHECK:       bb1:
439*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
440a92e1971Skhei4; CHECK-NEXT:    ret void
441a92e1971Skhei4;
442a92e1971Skhei4  %src = alloca i32, align 4
443a92e1971Skhei4  %dest = alloca i32, align 4
444a92e1971Skhei4  call void @llvm.lifetime.start.p0(i64 4, ptr nocapture %src)
445a92e1971Skhei4  call void @llvm.lifetime.start.p0(i64 4, ptr nocapture %dest)
446a92e1971Skhei4  store i32 42, ptr %src
447a92e1971Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
448a92e1971Skhei4  br label %bb0
449a92e1971Skhei4
450a92e1971Skhei4bb0:
451a92e1971Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 4, i1 false)
452a92e1971Skhei4  br label %bb1
453a92e1971Skhei4
454a92e1971Skhei4bb1:
455a92e1971Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
456a92e1971Skhei4  call void @llvm.lifetime.end.p0(i64 4, ptr nocapture %src)
457a92e1971Skhei4  call void @llvm.lifetime.end.p0(i64 4, ptr nocapture %dest)
458a92e1971Skhei4  ret void
459a92e1971Skhei4}
460a92e1971Skhei4
461a92e1971Skhei4define void @multi_bb_load_store(i1 %b) {
462a92e1971Skhei4; CHECK-LABEL: define void @multi_bb_load_store
463a92e1971Skhei4; CHECK-SAME: (i1 [[B:%.*]]) {
464a92e1971Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca i32, align 4
465a92e1971Skhei4; CHECK-NEXT:    store i32 42, ptr [[SRC]], align 4
466*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
467e0911b98Skhei4; CHECK-NEXT:    br label [[BB0:%.*]]
468e0911b98Skhei4; CHECK:       bb0:
469*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
470e0911b98Skhei4; CHECK-NEXT:    ret void
471e0911b98Skhei4;
472e0911b98Skhei4  %src = alloca i32, align 4
473e0911b98Skhei4  %dest = alloca i32, align 4
474e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 4, ptr nocapture %src)
475e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 4, ptr nocapture %dest)
476e0911b98Skhei4  store i32 42, ptr %src
477e0911b98Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
478e0911b98Skhei4
479e0911b98Skhei4  %src.val = load i32, ptr %src
480e0911b98Skhei4  store i32 %src.val, ptr %dest
481e0911b98Skhei4  br label %bb0
482e0911b98Skhei4
483e0911b98Skhei4bb0:
484e0911b98Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
485e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 4, ptr nocapture %src)
486e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 4, ptr nocapture %dest)
487e0911b98Skhei4  ret void
488e0911b98Skhei4}
489e0911b98Skhei4
490e0911b98Skhei4; FIXME: merge allocas for bb-separated, but logically straight.
491e0911b98Skhei4; We might be handle those load/store MemCpyOpt totally
492e0911b98Skhei4define void @multi_bb_separated_load_store(i1 %b) {
493e0911b98Skhei4; CHECK-LABEL: define void @multi_bb_separated_load_store
494e0911b98Skhei4; CHECK-SAME: (i1 [[B:%.*]]) {
495e0911b98Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca i32, align 4
496e0911b98Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca i32, align 4
497*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr captures(none) [[SRC]])
498*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr captures(none) [[DEST]])
499e0911b98Skhei4; CHECK-NEXT:    store i32 42, ptr [[SRC]], align 4
500*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
501e0911b98Skhei4; CHECK-NEXT:    [[SRC_VAL:%.*]] = load i32, ptr [[SRC]], align 4
502a92e1971Skhei4; CHECK-NEXT:    br label [[BB0:%.*]]
503a92e1971Skhei4; CHECK:       bb0:
504a92e1971Skhei4; CHECK-NEXT:    store i32 [[SRC_VAL]], ptr [[DEST]], align 4
505a92e1971Skhei4; CHECK-NEXT:    br label [[BB1:%.*]]
506a92e1971Skhei4; CHECK:       bb1:
507*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[DEST]])
508*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr captures(none) [[SRC]])
509*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr captures(none) [[DEST]])
510a92e1971Skhei4; CHECK-NEXT:    ret void
511a92e1971Skhei4;
512a92e1971Skhei4  %src = alloca i32, align 4
513a92e1971Skhei4  %dest = alloca i32, align 4
514a92e1971Skhei4  call void @llvm.lifetime.start.p0(i64 4, ptr nocapture %src)
515a92e1971Skhei4  call void @llvm.lifetime.start.p0(i64 4, ptr nocapture %dest)
516a92e1971Skhei4  store i32 42, ptr %src
517a92e1971Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
518a92e1971Skhei4
519a92e1971Skhei4  %src.val = load i32, ptr %src
520a92e1971Skhei4  br label %bb0
521a92e1971Skhei4
522a92e1971Skhei4bb0:
523a92e1971Skhei4  store i32 %src.val, ptr %dest
524a92e1971Skhei4  br label %bb1
525a92e1971Skhei4
526a92e1971Skhei4bb1:
527a92e1971Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
528a92e1971Skhei4  call void @llvm.lifetime.end.p0(i64 4, ptr nocapture %src)
529a92e1971Skhei4  call void @llvm.lifetime.end.p0(i64 4, ptr nocapture %dest)
530a92e1971Skhei4  ret void
531a92e1971Skhei4}
532a92e1971Skhei4
533a92e1971Skhei4define void @multi_bb_simple_br(i1 %b) {
534a92e1971Skhei4; CHECK-LABEL: define void @multi_bb_simple_br
53539321564Skhei4; CHECK-SAME: (i1 [[B:%.*]]) {
53639321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
53739321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
538*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
53939321564Skhei4; CHECK-NEXT:    br i1 [[B]], label [[BB0:%.*]], label [[BB1:%.*]]
54039321564Skhei4; CHECK:       bb0:
541*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
54239321564Skhei4; CHECK-NEXT:    br label [[BB2:%.*]]
54339321564Skhei4; CHECK:       bb1:
544*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
54539321564Skhei4; CHECK-NEXT:    br label [[BB2]]
54639321564Skhei4; CHECK:       bb2:
54739321564Skhei4; CHECK-NEXT:    ret void
54839321564Skhei4;
54939321564Skhei4  %src = alloca %struct.Foo, align 4
55039321564Skhei4  %dest = alloca %struct.Foo, align 4
55139321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
55239321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
55339321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
55439321564Skhei4  %1 = call i32 @use_nocapture(ptr noundef nocapture %src)
55539321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
55639321564Skhei4  br i1 %b, label %bb0, label %bb1
55739321564Skhei4
55839321564Skhei4bb0:
55939321564Skhei4  %2 = call i32 @use_nocapture(ptr noundef nocapture %dest)
56039321564Skhei4  br label %bb2
56139321564Skhei4
56239321564Skhei4bb1:
56339321564Skhei4  %3 = call i32 @use_nocapture(ptr noundef nocapture %dest)
56439321564Skhei4  br label %bb2
56539321564Skhei4
56639321564Skhei4bb2:
56739321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
56839321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
56939321564Skhei4  ret void
57039321564Skhei4}
57139321564Skhei4
572fe285ae0Skhei4; Test for BasicBlock and Instruction mixed dominator finding.
573fe285ae0Skhei4define void @multi_bb_dom_test0(i1 %b) {
574fe285ae0Skhei4; CHECK-LABEL: define void @multi_bb_dom_test0
575fe285ae0Skhei4; CHECK-SAME: (i1 [[B:%.*]]) {
576fe285ae0Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
577fe285ae0Skhei4; CHECK-NEXT:    br i1 [[B]], label [[BB0:%.*]], label [[BB1:%.*]]
578fe285ae0Skhei4; CHECK:       bb0:
579fe285ae0Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
580fe285ae0Skhei4; CHECK-NEXT:    br label [[BB2:%.*]]
581fe285ae0Skhei4; CHECK:       bb1:
582fe285ae0Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 40, i32 50, i32 60 }, ptr [[SRC]], align 4
583fe285ae0Skhei4; CHECK-NEXT:    br label [[BB2]]
584fe285ae0Skhei4; CHECK:       bb2:
585*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
586fe285ae0Skhei4; CHECK-NEXT:    ret void
587fe285ae0Skhei4;
588fe285ae0Skhei4  %src = alloca %struct.Foo, align 4
589fe285ae0Skhei4  %dest = alloca %struct.Foo, align 4
590fe285ae0Skhei4  br i1 %b, label %bb0, label %bb1
591fe285ae0Skhei4
592fe285ae0Skhei4bb0:
593fe285ae0Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
594fe285ae0Skhei4  br label %bb2
595fe285ae0Skhei4
596fe285ae0Skhei4bb1:
597fe285ae0Skhei4  store %struct.Foo { i32 40, i32 50, i32 60 }, ptr %src
598fe285ae0Skhei4  br label %bb2
599fe285ae0Skhei4
600fe285ae0Skhei4bb2:
601fe285ae0Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
602c652987dSkhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
603fe285ae0Skhei4  %1 = call i32 @use_nocapture(ptr noundef nocapture %dest)
604fe285ae0Skhei4
605fe285ae0Skhei4  ret void
606fe285ae0Skhei4
607fe285ae0Skhei4}
608fe285ae0Skhei4
60998d1b0ebSkhei4; Test for BasicBlock and Instruction mixed dominator finding.
61098d1b0ebSkhei4define void @multi_bb_dom_test1(i1 %b) {
61198d1b0ebSkhei4; CHECK-LABEL: define void @multi_bb_dom_test1
61298d1b0ebSkhei4; CHECK-SAME: (i1 [[B:%.*]]) {
61398d1b0ebSkhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
61498d1b0ebSkhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
61598d1b0ebSkhei4; CHECK-NEXT:    br i1 [[B]], label [[BB0:%.*]], label [[BB1:%.*]]
61698d1b0ebSkhei4; CHECK:       bb0:
61798d1b0ebSkhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
61898d1b0ebSkhei4; CHECK-NEXT:    br label [[BB2:%.*]]
61998d1b0ebSkhei4; CHECK:       bb1:
62098d1b0ebSkhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 40, i32 50, i32 60 }, ptr [[SRC]], align 4
62198d1b0ebSkhei4; CHECK-NEXT:    br label [[BB2]]
62298d1b0ebSkhei4; CHECK:       bb2:
623*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
62498d1b0ebSkhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
625*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[DEST]])
62698d1b0ebSkhei4; CHECK-NEXT:    ret void
62798d1b0ebSkhei4; CHECK:       unr:
628*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[DEST]])
62998d1b0ebSkhei4; CHECK-NEXT:    br label [[BB2]]
63098d1b0ebSkhei4;
63198d1b0ebSkhei4  %src = alloca %struct.Foo, align 4
63298d1b0ebSkhei4  %dest = alloca %struct.Foo, align 4
63398d1b0ebSkhei4  br i1 %b, label %bb0, label %bb1
63498d1b0ebSkhei4
63598d1b0ebSkhei4bb0:
63698d1b0ebSkhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
63798d1b0ebSkhei4  br label %bb2
63898d1b0ebSkhei4
63998d1b0ebSkhei4bb1:
64098d1b0ebSkhei4  store %struct.Foo { i32 40, i32 50, i32 60 }, ptr %src
64198d1b0ebSkhei4  br label %bb2
64298d1b0ebSkhei4
64398d1b0ebSkhei4bb2:
64498d1b0ebSkhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
64598d1b0ebSkhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false); 1
64698d1b0ebSkhei4  %1 = call i32 @use_nocapture(ptr noundef nocapture %dest)
64798d1b0ebSkhei4
64898d1b0ebSkhei4  ret void
64998d1b0ebSkhei4
65098d1b0ebSkhei4unr:
65198d1b0ebSkhei4  %2 = call i32 @use_nocapture(ptr noundef nocapture %dest)
65298d1b0ebSkhei4  br label %bb2
65398d1b0ebSkhei4}
65498d1b0ebSkhei4
655e0911b98Skhei4; Test for BasicBlock and Instruction mixed post-dominator finding.
656e0911b98Skhei4define void @multi_bb_pdom_test0(i1 %b) {
657e0911b98Skhei4; CHECK-LABEL: define void @multi_bb_pdom_test0
658e0911b98Skhei4; CHECK-SAME: (i1 [[B:%.*]]) {
659e0911b98Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
660e0911b98Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
661e0911b98Skhei4; CHECK-NEXT:    br i1 [[B]], label [[BB0:%.*]], label [[BB1:%.*]]
662e0911b98Skhei4; CHECK:       bb0:
663*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
664e0911b98Skhei4; CHECK-NEXT:    br label [[BB2:%.*]]
665e0911b98Skhei4; CHECK:       bb1:
666*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
667e0911b98Skhei4; CHECK-NEXT:    br label [[BB2]]
668e0911b98Skhei4; CHECK:       bb2:
669*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
670e0911b98Skhei4; CHECK-NEXT:    ret void
671e0911b98Skhei4;
672e0911b98Skhei4  %src = alloca %struct.Foo, align 4
673e0911b98Skhei4  %dest = alloca %struct.Foo, align 4
674e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
675e0911b98Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
676e0911b98Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false); 1
677e0911b98Skhei4  br i1 %b, label %bb0, label %bb1
678e0911b98Skhei4
679e0911b98Skhei4bb0:
680e0911b98Skhei4  %1 = call i32 @use_nocapture(ptr noundef nocapture %dest)
681e0911b98Skhei4  br label %bb2
682e0911b98Skhei4
683e0911b98Skhei4bb1:
684e0911b98Skhei4  %2 = call i32 @use_nocapture(ptr noundef nocapture %dest)
685e0911b98Skhei4  br label %bb2
686e0911b98Skhei4
687e0911b98Skhei4bb2:
688e0911b98Skhei4  %3 = call i32 @use_nocapture(ptr noundef nocapture %dest)
689e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
690e0911b98Skhei4  ret void
691e0911b98Skhei4
692e0911b98Skhei4  uselistorder ptr %dest, {  2, 3, 0, 1, 4, 5 }
693e0911b98Skhei4}
694e0911b98Skhei4
695e0911b98Skhei4; Test for inserting lifetime.end after the phi-node
696e0911b98Skhei4define void @multi_bb_pdom_test1(i1 %b) {
697e0911b98Skhei4; CHECK-LABEL: define void @multi_bb_pdom_test1
698e0911b98Skhei4; CHECK-SAME: (i1 [[B:%.*]]) {
699e0911b98Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
700e0911b98Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
701e0911b98Skhei4; CHECK-NEXT:    br i1 [[B]], label [[BB0:%.*]], label [[BB1:%.*]]
702e0911b98Skhei4; CHECK:       bb0:
703*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
704e0911b98Skhei4; CHECK-NEXT:    br label [[BB2:%.*]]
705e0911b98Skhei4; CHECK:       bb1:
706*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
707e0911b98Skhei4; CHECK-NEXT:    br label [[BB2]]
708e0911b98Skhei4; CHECK:       bb2:
709e0911b98Skhei4; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 42, [[BB0]] ], [ 41, [[BB1]] ]
710e0911b98Skhei4; CHECK-NEXT:    ret void
711e0911b98Skhei4;
712e0911b98Skhei4  %src = alloca %struct.Foo, align 4
713e0911b98Skhei4  %dest = alloca %struct.Foo, align 4
714e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
715e0911b98Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
716e0911b98Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false); 1
717e0911b98Skhei4  br i1 %b, label %bb0, label %bb1
718e0911b98Skhei4
719e0911b98Skhei4bb0:
720e0911b98Skhei4  %1 = call i32 @use_nocapture(ptr noundef nocapture %dest)
721e0911b98Skhei4  br label %bb2
722e0911b98Skhei4
723e0911b98Skhei4bb1:
724e0911b98Skhei4  %2 = call i32 @use_nocapture(ptr noundef nocapture %dest)
725e0911b98Skhei4  br label %bb2
726e0911b98Skhei4
727e0911b98Skhei4bb2:
728e0911b98Skhei4  %i = phi i32 [ 42, %bb0 ], [ 41, %bb1 ]
729e0911b98Skhei4  ret void
730e0911b98Skhei4
731e0911b98Skhei4}
732e0911b98Skhei4
7335a9a7f53Skhei4; Test for existing unreachable cycle
7345a9a7f53Skhei4define void @multi_bb_pdom_test2(i1 %b) {
7355a9a7f53Skhei4; CHECK-LABEL: define void @multi_bb_pdom_test2
7365a9a7f53Skhei4; CHECK-SAME: (i1 [[B:%.*]]) {
7375a9a7f53Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
7385a9a7f53Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
739*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
7405a9a7f53Skhei4; CHECK-NEXT:    ret void
7415a9a7f53Skhei4; CHECK:       unr1:
742*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
7435a9a7f53Skhei4; CHECK-NEXT:    br label [[UNR2:%.*]]
7445a9a7f53Skhei4; CHECK:       unr2:
745*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
7465a9a7f53Skhei4; CHECK-NEXT:    br label [[UNR1:%.*]]
7475a9a7f53Skhei4;
7485a9a7f53Skhei4  %src = alloca %struct.Foo, align 4
7495a9a7f53Skhei4  %dest = alloca %struct.Foo, align 4
7505a9a7f53Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
7515a9a7f53Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
7525a9a7f53Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false); 1
7535a9a7f53Skhei4  %1 = call i32 @use_nocapture(ptr noundef nocapture %dest)
7545a9a7f53Skhei4  ret void
7555a9a7f53Skhei4
7565a9a7f53Skhei4unr1:
7575a9a7f53Skhei4  %2 = call i32 @use_nocapture(ptr noundef nocapture %dest)
7585a9a7f53Skhei4  br label %unr2
7595a9a7f53Skhei4
7605a9a7f53Skhei4unr2:
7615a9a7f53Skhei4  %3 = call i32 @use_nocapture(ptr noundef nocapture %dest)
7625a9a7f53Skhei4  br label %unr1
7635a9a7f53Skhei4
7645a9a7f53Skhei4}
7655a9a7f53Skhei4
766e0911b98Skhei4define void @multi_bb_loop(i32 %n) {
767e0911b98Skhei4; CHECK-LABEL: define void @multi_bb_loop
76839321564Skhei4; CHECK-SAME: (i32 [[N:%.*]]) {
76939321564Skhei4; CHECK-NEXT:  entry:
77039321564Skhei4; CHECK-NEXT:    [[NLT1:%.*]] = icmp slt i32 [[N]], 1
77139321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 8
77239321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 0, i32 1, i32 42 }, ptr [[SRC]], align 4
77339321564Skhei4; CHECK-NEXT:    br i1 [[NLT1]], label [[LOOP_EXIT:%.*]], label [[LOOP_BODY:%.*]]
77439321564Skhei4; CHECK:       loop_body:
77539321564Skhei4; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[NEW_I:%.*]], [[LOOP_BODY]] ], [ 1, [[ENTRY:%.*]] ]
77639321564Skhei4; CHECK-NEXT:    [[NEW_I]] = add i32 [[I]], 1
777e0911b98Skhei4; CHECK-NEXT:    store i32 [[NEW_I]], ptr [[SRC]], align 4
77839321564Skhei4; CHECK-NEXT:    [[IGTN:%.*]] = icmp sgt i32 [[NEW_I]], [[N]]
77939321564Skhei4; CHECK-NEXT:    br i1 [[IGTN]], label [[LOOP_EXIT]], label [[LOOP_BODY]]
78039321564Skhei4; CHECK:       loop_exit:
781e0911b98Skhei4; CHECK-NEXT:    ret void
78239321564Skhei4;
78339321564Skhei4entry:
78439321564Skhei4  %nlt1 = icmp slt i32 %n, 1
78539321564Skhei4  %src = alloca %struct.Foo, align 8
78639321564Skhei4  %dest = alloca %struct.Foo, align 8
78739321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
78839321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
78939321564Skhei4  store %struct.Foo { i32 0, i32 1, i32 42 }, ptr %src
79039321564Skhei4  br i1 %nlt1, label %loop_exit, label %loop_body
79139321564Skhei4
79239321564Skhei4loop_body:
79339321564Skhei4  %i = phi i32 [ %new_i, %loop_body ], [ 1, %entry ]
79439321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %dest, ptr align 8 %src, i64 12, i1 false)
79539321564Skhei4  %new_i = add i32 %i, 1
796e0911b98Skhei4  store i32 %new_i, ptr %src
79739321564Skhei4  %igtn = icmp sgt i32 %new_i, %n
79839321564Skhei4  br i1 %igtn, label %loop_exit, label %loop_body
79939321564Skhei4
80039321564Skhei4loop_exit:
801e0911b98Skhei4  ret void
802e0911b98Skhei4}
803e0911b98Skhei4
804e0911b98Skhei4define void @multi_bb_unreachable_modref(i1 %b0) {
805e0911b98Skhei4; CHECK-LABEL: define void @multi_bb_unreachable_modref
806e0911b98Skhei4; CHECK-SAME: (i1 [[B0:%.*]]) {
807e0911b98Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
808e0911b98Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
809*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
810e0911b98Skhei4; CHECK-NEXT:    br i1 [[B0]], label [[BB0:%.*]], label [[EXIT:%.*]]
811e0911b98Skhei4; CHECK:       exit:
812*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
813e0911b98Skhei4; CHECK-NEXT:    ret void
814e0911b98Skhei4; CHECK:       bb0:
815e0911b98Skhei4; CHECK-NEXT:    ret void
816e0911b98Skhei4;
817e0911b98Skhei4  %src = alloca %struct.Foo, align 4
818e0911b98Skhei4  %dest = alloca %struct.Foo, align 4
819e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
820e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
821e0911b98Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
822e0911b98Skhei4  %1 = call i32 @use_nocapture(ptr noundef nocapture %src)
823e0911b98Skhei4  br i1 %b0, label %bb0, label %exit
824e0911b98Skhei4
825e0911b98Skhei4exit:
826e0911b98Skhei4  %2 = call i32 @use_nocapture(ptr noundef nocapture %src)
827e0911b98Skhei4  ret void
828e0911b98Skhei4
829e0911b98Skhei4bb0:
830e0911b98Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
831e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
832e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
833e0911b98Skhei4  ret void
834e0911b98Skhei4}
835e0911b98Skhei4
836e0911b98Skhei4define void @multi_bb_non_dominated(i1 %b0, i1 %b1) {
837e0911b98Skhei4; CHECK-LABEL: define void @multi_bb_non_dominated
838e0911b98Skhei4; CHECK-SAME: (i1 [[B0:%.*]], i1 [[B1:%.*]]) {
839e0911b98Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
840e0911b98Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
841*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
842e0911b98Skhei4; CHECK-NEXT:    br i1 [[B0]], label [[BB0:%.*]], label [[BB1:%.*]]
843e0911b98Skhei4; CHECK:       bb0:
844e0911b98Skhei4; CHECK-NEXT:    br label [[BB2:%.*]]
845e0911b98Skhei4; CHECK:       bb1:
846*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
847e0911b98Skhei4; CHECK-NEXT:    br label [[BB2]]
848e0911b98Skhei4; CHECK:       bb2:
849e0911b98Skhei4; CHECK-NEXT:    ret void
850e0911b98Skhei4;
851e0911b98Skhei4  %src = alloca %struct.Foo, align 4
852e0911b98Skhei4  %dest = alloca %struct.Foo, align 4
853e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
854e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
855e0911b98Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
856e0911b98Skhei4  %1 = call i32 @use_nocapture(ptr noundef nocapture %src)
857e0911b98Skhei4  br i1 %b0, label %bb0, label %bb1
858e0911b98Skhei4
859e0911b98Skhei4bb0:
860e0911b98Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
861e0911b98Skhei4  br label %bb2
862e0911b98Skhei4
863e0911b98Skhei4bb1:
864e0911b98Skhei4  %2 = call i32 @use_nocapture(ptr noundef nocapture %src)
865e0911b98Skhei4  br label %bb2
866e0911b98Skhei4
867e0911b98Skhei4bb2:
868e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
869e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
870e0911b98Skhei4  ret void
871e0911b98Skhei4}
872e0911b98Skhei4
873e0911b98Skhei4; TODO: to merge following `is_def` cases, we need to do liveness analysis
874e0911b98Skhei4; or something that distinguish the full-size-Mod as a Def.
875e0911b98Skhei4; Tests that a memcpy that completely overwrites a stack value is a definition
876e0911b98Skhei4; for the purposes of liveness analysis.
877e0911b98Skhei4define void @memcpy_is_def() {
878e0911b98Skhei4; CHECK-LABEL: define void @memcpy_is_def() {
879e0911b98Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
880e0911b98Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
881*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
882*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
883e0911b98Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
884*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
885e0911b98Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
886*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[DEST]])
887e0911b98Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[SRC]], ptr align 4 [[DEST]], i64 12, i1 false)
888*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
889*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
890*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
891e0911b98Skhei4; CHECK-NEXT:    ret void
892e0911b98Skhei4;
893e0911b98Skhei4  %src = alloca %struct.Foo, align 4
894e0911b98Skhei4  %dest = alloca %struct.Foo, align 4
895e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
896e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
897e0911b98Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
898e0911b98Skhei4  %1 = call i32 @use_nocapture(ptr noundef nocapture %src)
899e0911b98Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
900e0911b98Skhei4  %2 = call i32 @use_nocapture(ptr noundef nocapture %dest)
901e0911b98Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %src, ptr align 4 %dest, i64 12, i1 false)
902e0911b98Skhei4  %3 = call i32 @use_nocapture(ptr noundef nocapture %src)
903e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
904e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
905e0911b98Skhei4  ret void
906e0911b98Skhei4}
907e0911b98Skhei4
908e0911b98Skhei4; TODO: merge allocas
909e0911b98Skhei4; Tests that a memset that completely overwrites a stack value is a definition
910e0911b98Skhei4; for the purposes of liveness analysis.
911e0911b98Skhei4define void @memset_is_def() {
912e0911b98Skhei4; CHECK-LABEL: define void @memset_is_def() {
913e0911b98Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
914e0911b98Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
915*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
916*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
917e0911b98Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
918*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
919e0911b98Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
920*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[DEST]])
921e0911b98Skhei4; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[SRC]], i8 42, i64 12, i1 false)
922*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
923*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
924*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
925e0911b98Skhei4; CHECK-NEXT:    ret void
926e0911b98Skhei4;
927e0911b98Skhei4  %src = alloca %struct.Foo, align 4
928e0911b98Skhei4  %dest = alloca %struct.Foo, align 4
929e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
930e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
931e0911b98Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
932e0911b98Skhei4  %1 = call i32 @use_nocapture(ptr noundef nocapture %src)
933e0911b98Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
934e0911b98Skhei4  %2 = call i32 @use_nocapture(ptr noundef nocapture %dest)
935e0911b98Skhei4  call void @llvm.memset.p0.i64(ptr align 4 %src, i8 42, i64 12, i1 false)
936e0911b98Skhei4  %3 = call i32 @use_nocapture(ptr noundef nocapture %src)
937e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
938e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
939e0911b98Skhei4  ret void
940e0911b98Skhei4}
941e0911b98Skhei4
942e0911b98Skhei4; TODO: merge allocas
943e0911b98Skhei4; Tests that a store that completely overwrites a stack value is a definition
944e0911b98Skhei4; for the purposes of liveness analysis.
945e0911b98Skhei4define void @store_is_def() {
946e0911b98Skhei4; CHECK-LABEL: define void @store_is_def() {
947e0911b98Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca i32, align 4
948e0911b98Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca i32, align 4
949*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr captures(none) [[SRC]])
950*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr captures(none) [[DEST]])
951e0911b98Skhei4; CHECK-NEXT:    store i32 42, ptr [[SRC]], align 4
952*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
953e0911b98Skhei4; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[SRC]], align 4
954e0911b98Skhei4; CHECK-NEXT:    store i32 [[TMP2]], ptr [[DEST]], align 4
955*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[DEST]])
956e0911b98Skhei4; CHECK-NEXT:    store i32 64, ptr [[SRC]], align 4
957*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP4:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
958*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr captures(none) [[SRC]])
959*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr captures(none) [[DEST]])
960e0911b98Skhei4; CHECK-NEXT:    ret void
961e0911b98Skhei4;
962e0911b98Skhei4  %src = alloca i32, align 4
963e0911b98Skhei4  %dest = alloca i32, align 4
964e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 4, ptr nocapture %src)
965e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 4, ptr nocapture %dest)
966e0911b98Skhei4  store i32 42, ptr %src
967e0911b98Skhei4  %1 = call i32 @use_nocapture(ptr noundef nocapture %src)
968e0911b98Skhei4  %2 = load i32, ptr %src
969e0911b98Skhei4  store i32 %2, ptr %dest
970e0911b98Skhei4  %3 = call i32 @use_nocapture(ptr noundef nocapture %dest)
971e0911b98Skhei4  store i32 64, ptr %src
972e0911b98Skhei4  %4 = call i32 @use_nocapture(ptr noundef nocapture %src)
973e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 4, ptr nocapture %src)
974e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 4, ptr nocapture %dest)
975e0911b98Skhei4  ret void
97639321564Skhei4}
97739321564Skhei4
978c4d37c35Skhei4; TODO: merge src and dest, because any execution path doesn't cause conflicts.
979c4d37c35Skhei4; Tests that exists modref for both src/dest, but it never conflict on the execution.
980c4d37c35Skhei4define void @multi_bb_dataflow(i1 %b) {
981c4d37c35Skhei4; CHECK-LABEL: define void @multi_bb_dataflow
982c4d37c35Skhei4; CHECK-SAME: (i1 [[B:%.*]]) {
983c4d37c35Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
984c4d37c35Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
985*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
986*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
987c4d37c35Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
988*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
989c4d37c35Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
990c4d37c35Skhei4; CHECK-NEXT:    br i1 [[B]], label [[BB0:%.*]], label [[BB1:%.*]]
991c4d37c35Skhei4; CHECK:       bb0:
992*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
993c4d37c35Skhei4; CHECK-NEXT:    br label [[BB2:%.*]]
994c4d37c35Skhei4; CHECK:       bb1:
995*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[DEST]])
996c4d37c35Skhei4; CHECK-NEXT:    br label [[BB2]]
997c4d37c35Skhei4; CHECK:       bb2:
998*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
999*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
1000c4d37c35Skhei4; CHECK-NEXT:    ret void
1001c4d37c35Skhei4;
1002c4d37c35Skhei4  %src = alloca %struct.Foo, align 4
1003c4d37c35Skhei4  %dest = alloca %struct.Foo, align 4
1004c4d37c35Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
1005c4d37c35Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
1006c4d37c35Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
1007c4d37c35Skhei4  %1 = call i32 @use_nocapture(ptr noundef nocapture %src)
1008c4d37c35Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
1009c4d37c35Skhei4  br i1 %b, label %bb0, label %bb1
1010c4d37c35Skhei4
1011c4d37c35Skhei4bb0:
1012c4d37c35Skhei4  %2 = call i32 @use_nocapture(ptr noundef nocapture %src)
1013c4d37c35Skhei4  br label %bb2
1014c4d37c35Skhei4
1015c4d37c35Skhei4bb1:
1016c4d37c35Skhei4  %3 = call i32 @use_nocapture(ptr noundef nocapture %dest)
1017c4d37c35Skhei4  br label %bb2
1018c4d37c35Skhei4
1019c4d37c35Skhei4bb2:
1020c4d37c35Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
1021c4d37c35Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
1022c4d37c35Skhei4  ret void
1023c4d37c35Skhei4}
1024c4d37c35Skhei4
1025c4d37c35Skhei4
102639321564Skhei4; Optimization failures follow:
102739321564Skhei4
1028e0911b98Skhei4; Tests that a memcpy that doesn't completely overwrite a stack value is a use
1029e0911b98Skhei4; for the purposes of liveness analysis, not a definition.
1030e0911b98Skhei4define void @incomplete_memcpy() {
1031e0911b98Skhei4; CHECK-LABEL: define void @incomplete_memcpy() {
1032e0911b98Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
1033e0911b98Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
1034*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1035*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
1036e0911b98Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
1037*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
1038e0911b98Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 11, i1 false)
1039*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[DEST]])
1040*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
1041*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
1042e0911b98Skhei4; CHECK-NEXT:    ret void
1043e0911b98Skhei4;
1044e0911b98Skhei4  %src = alloca %struct.Foo, align 4
1045e0911b98Skhei4  %dest = alloca %struct.Foo, align 4
1046e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
1047e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
1048e0911b98Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
1049e0911b98Skhei4  %1 = call i32 @use_nocapture(ptr noundef nocapture %src)
1050e0911b98Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 11, i1 false)
1051e0911b98Skhei4  %2 = call i32 @use_nocapture(ptr noundef nocapture %dest)
1052e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
1053e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
1054e0911b98Skhei4  ret void
1055e0911b98Skhei4}
1056e0911b98Skhei4
1057e0911b98Skhei4; Tests that a store that doesn't completely overwrite a stack value is a use
1058e0911b98Skhei4; for the purposes of liveness analysis, not a definition.
1059e0911b98Skhei4define void @incomplete_store() {
1060e0911b98Skhei4; CHECK-LABEL: define void @incomplete_store() {
1061e0911b98Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
1062e0911b98Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
1063*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1064*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
1065e0911b98Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
1066*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
1067e0911b98Skhei4; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[SRC]], align 4
1068e0911b98Skhei4; CHECK-NEXT:    store i32 [[TMP2]], ptr [[DEST]], align 4
1069*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[DEST]])
1070*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
1071*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
1072e0911b98Skhei4; CHECK-NEXT:    ret void
1073e0911b98Skhei4;
1074e0911b98Skhei4  %src = alloca %struct.Foo, align 4
1075e0911b98Skhei4  %dest = alloca %struct.Foo, align 4
1076e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
1077e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
1078e0911b98Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
1079e0911b98Skhei4  %1 = call i32 @use_nocapture(ptr noundef nocapture %src)
1080e0911b98Skhei4  %2 = load i32, ptr %src
1081e0911b98Skhei4  store i32 %2, ptr %dest
1082e0911b98Skhei4  %3 = call i32 @use_nocapture(ptr noundef nocapture %dest)
1083e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
1084e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
1085e0911b98Skhei4  ret void
1086e0911b98Skhei4}
1087e0911b98Skhei4
108839321564Skhei4; Tests that dynamically-sized allocas are never merged.
108939321564Skhei4define void @dynamically_sized_alloca(i64 %i) {
109039321564Skhei4; CHECK-LABEL: define void @dynamically_sized_alloca
109139321564Skhei4; CHECK-SAME: (i64 [[I:%.*]]) {
109239321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca i8, i64 [[I]], align 4
109339321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca i8, i64 [[I]], align 4
1094*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 -1, ptr captures(none) [[SRC]])
1095*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 -1, ptr captures(none) [[DEST]])
109639321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO:%.*]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
1097*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
109839321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
1099*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[DEST]])
1100*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 -1, ptr captures(none) [[SRC]])
1101*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 -1, ptr captures(none) [[DEST]])
110239321564Skhei4; CHECK-NEXT:    ret void
110339321564Skhei4;
110439321564Skhei4  %src = alloca i8, i64 %i, align 4
110539321564Skhei4  %dest = alloca i8, i64 %i, align 4
110639321564Skhei4  call void @llvm.lifetime.start.p0(i64 -1, ptr nocapture %src)
110739321564Skhei4  call void @llvm.lifetime.start.p0(i64 -1, ptr nocapture %dest)
110839321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
110939321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
111039321564Skhei4
111139321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
111239321564Skhei4
111339321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
111439321564Skhei4  call void @llvm.lifetime.end.p0(i64 -1, ptr nocapture %src)
111539321564Skhei4  call void @llvm.lifetime.end.p0(i64 -1, ptr nocapture %dest)
111639321564Skhei4  ret void
111739321564Skhei4}
111839321564Skhei4
111939321564Skhei4
112039321564Skhei4; Tests that inalloca attributed allocas are never merged, to prevent stacksave/stackrestore handling.
112139321564Skhei4define void @inalloca() {
112239321564Skhei4; CHECK-LABEL: define void @inalloca() {
112339321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
112439321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca inalloca [[STRUCT_FOO]], align 4
1125*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1126*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
112739321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
1128*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
112939321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
1130*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[DEST]])
1131*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
1132*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
113339321564Skhei4; CHECK-NEXT:    ret void
113439321564Skhei4;
113539321564Skhei4  %src = alloca %struct.Foo, align 4
113639321564Skhei4  %dest = alloca inalloca %struct.Foo, align 4
113739321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
113839321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
113939321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
114039321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
114139321564Skhei4
114239321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
114339321564Skhei4
114439321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
114539321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
114639321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
114739321564Skhei4  ret void
114839321564Skhei4}
114939321564Skhei4
115039321564Skhei4; Tests that a memcpy with a dynamic size is never optimized.
115139321564Skhei4define void @dynamically_sized_memcpy(i64 %size) {
115239321564Skhei4; CHECK-LABEL: define void @dynamically_sized_memcpy
115339321564Skhei4; CHECK-SAME: (i64 [[SIZE:%.*]]) {
115439321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
115539321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
1156*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1157*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
115839321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
1159*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
116039321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 [[SIZE]], i1 false)
1161*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[DEST]])
1162*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
1163*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
116439321564Skhei4; CHECK-NEXT:    ret void
116539321564Skhei4;
116639321564Skhei4  %src = alloca %struct.Foo, align 4
116739321564Skhei4  %dest = alloca %struct.Foo, align 4
116839321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
116939321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
117039321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
117139321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
117239321564Skhei4
117339321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 %size, i1 false)
117439321564Skhei4
117539321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
117639321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
117739321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
117839321564Skhei4  ret void
117939321564Skhei4}
118039321564Skhei4
118139321564Skhei4; Tests that allocas with different sizes aren't merged together.
118239321564Skhei4define void @mismatched_alloca_size() {
118339321564Skhei4; CHECK-LABEL: define void @mismatched_alloca_size() {
118439321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca i8, i64 24, align 4
118539321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca i8, i64 12, align 4
1186*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 24, ptr captures(none) [[SRC]])
1187*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
118839321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO:%.*]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
1189*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
119039321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
1191*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[DEST]])
1192*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 24, ptr captures(none) [[SRC]])
1193*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
119439321564Skhei4; CHECK-NEXT:    ret void
119539321564Skhei4;
119639321564Skhei4  %src = alloca i8, i64 24, align 4
119739321564Skhei4  %dest = alloca i8, i64 12, align 4
119839321564Skhei4  call void @llvm.lifetime.start.p0(i64 24, ptr nocapture %src)
119939321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
120039321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
120139321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
120239321564Skhei4
120339321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
120439321564Skhei4
120539321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
120639321564Skhei4  call void @llvm.lifetime.end.p0(i64 24, ptr nocapture %src)
120739321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
120839321564Skhei4  ret void
120939321564Skhei4}
121039321564Skhei4
121139321564Skhei4; Tests that allocas with mismatched address spaces aren't combined.
121239321564Skhei4define void @mismatched_alloca_addrspace() {
121339321564Skhei4; CHECK-LABEL: define void @mismatched_alloca_addrspace() {
121439321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca i8, i64 24, align 4, addrspace(1)
121539321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca i8, i64 12, align 4, addrspace(2)
1216*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p1(i64 24, ptr addrspace(1) captures(none) [[SRC]])
1217*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p2(i64 12, ptr addrspace(2) captures(none) [[DEST]])
121839321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO:%.*]] { i32 10, i32 20, i32 30 }, ptr addrspace(1) [[SRC]], align 4
1219*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr addrspace(1) captures(none) [[SRC]])
122039321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p2.p1.i64(ptr addrspace(2) align 4 [[DEST]], ptr addrspace(1) align 4 [[SRC]], i64 12, i1 false)
1221*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p1(i64 24, ptr addrspace(1) captures(none) [[SRC]])
1222*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr addrspace(2) captures(none) [[DEST]])
1223*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p2(i64 12, ptr addrspace(2) captures(none) [[DEST]])
122439321564Skhei4; CHECK-NEXT:    ret void
122539321564Skhei4;
122639321564Skhei4  %src = alloca i8, i64 24, align 4, addrspace(1)
122739321564Skhei4  %dest = alloca i8, i64 12, align 4, addrspace(2)
122839321564Skhei4  call void @llvm.lifetime.start.p1(i64 24, ptr addrspace(1) nocapture %src)
122939321564Skhei4  call void @llvm.lifetime.start.p2(i64 12, ptr addrspace(2) nocapture %dest)
123039321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr addrspace(1) %src
123139321564Skhei4  %1 = call i32 @use_nocapture(ptr addrspace(1) nocapture %src)
123239321564Skhei4
123339321564Skhei4  call void @llvm.memcpy.p2.p1.i64(ptr addrspace(2) align 4 %dest, ptr addrspace(1) align 4 %src, i64 12, i1 false)
123439321564Skhei4
123539321564Skhei4  call void @llvm.lifetime.end.p1(i64 24, ptr addrspace(1) nocapture %src)
123639321564Skhei4  %2 = call i32 @use_nocapture(ptr addrspace(2) nocapture %dest)
123739321564Skhei4  call void @llvm.lifetime.end.p2(i64 12, ptr addrspace(2) nocapture %dest)
123839321564Skhei4  ret void
123939321564Skhei4}
124039321564Skhei4
124139321564Skhei4; Tests that volatile memcpys aren't removed.
124239321564Skhei4define void @volatile_memcpy() {
124339321564Skhei4; CHECK-LABEL: define void @volatile_memcpy() {
124439321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
124539321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
1246*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1247*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
124839321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
1249*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
125039321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 true)
1251*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[DEST]])
1252*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
1253*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
125439321564Skhei4; CHECK-NEXT:    ret void
125539321564Skhei4;
125639321564Skhei4  %src = alloca %struct.Foo, align 4
125739321564Skhei4  %dest = alloca %struct.Foo, align 4
125839321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
125939321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
126039321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
126139321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
126239321564Skhei4
126339321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 true)
126439321564Skhei4
126539321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
126639321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
126739321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
126839321564Skhei4  ret void
126939321564Skhei4}
127039321564Skhei4
127139321564Skhei4; Tests that the optimization isn't performed when the destination is captured.
127239321564Skhei4define void @dest_captured() {
127339321564Skhei4; CHECK-LABEL: define void @dest_captured() {
127439321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
127539321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
1276*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1277*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
127839321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
1279*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
128039321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
128139321564Skhei4; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_maycapture(ptr [[DEST]])
1282*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
1283*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
128439321564Skhei4; CHECK-NEXT:    ret void
128539321564Skhei4;
128639321564Skhei4  %src = alloca %struct.Foo, align 4
128739321564Skhei4  %dest = alloca %struct.Foo, align 4
128839321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
128939321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
129039321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
129139321564Skhei4
129239321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
129339321564Skhei4
129439321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
129539321564Skhei4  %2 = call i32 @use_maycapture(ptr %dest)
129639321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
129739321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
129839321564Skhei4  ret void
129939321564Skhei4}
130039321564Skhei4
130139321564Skhei4; Tests that the optimization isn't performed when the source is captured.
130239321564Skhei4define void @src_captured() {
130339321564Skhei4; CHECK-LABEL: define void @src_captured() {
130439321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
130539321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
1306*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1307*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
130839321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
130939321564Skhei4; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_maycapture(ptr [[SRC]])
131039321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
1311*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[DEST]])
1312*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
1313*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
131439321564Skhei4; CHECK-NEXT:    ret void
131539321564Skhei4;
131639321564Skhei4  %src = alloca %struct.Foo, align 4
131739321564Skhei4  %dest = alloca %struct.Foo, align 4
131839321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
131939321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
132039321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
132139321564Skhei4  %1 = call i32 @use_maycapture(ptr %src)
132239321564Skhei4
132339321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
132439321564Skhei4
132539321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
132639321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
132739321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
132839321564Skhei4  ret void
132939321564Skhei4}
133039321564Skhei4
133139321564Skhei4; Tests that failure if any modref exists before the copy,
133239321564Skhei4; Exactly ref seems safe because no mod say ref would be always undefined, but to make simple and conservative.
133339321564Skhei4define void @mod_ref_before_copy() {
133439321564Skhei4; CHECK-LABEL: define void @mod_ref_before_copy() {
133539321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
133639321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
1337*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1338*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
133939321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
1340*29441e4fSNikita Popov; CHECK-NEXT:    [[R:%.*]] = call i32 @use_readonly(ptr captures(none) [[DEST]])
1341*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
134239321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
1343*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
1344*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[DEST]])
1345*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
134639321564Skhei4; CHECK-NEXT:    ret void
134739321564Skhei4;
134839321564Skhei4  %src = alloca %struct.Foo, align 4
134939321564Skhei4  %dest = alloca %struct.Foo, align 4
135039321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
135139321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
135239321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
135339321564Skhei4  %r = call i32 @use_readonly(ptr nocapture %dest)
135439321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
135539321564Skhei4
135639321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
135739321564Skhei4
135839321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
135939321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
136039321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
136139321564Skhei4  ret void
136239321564Skhei4}
136339321564Skhei4
136439321564Skhei4; Tests that failure because copy semantics will change if dest is replaced with src.
136539321564Skhei4define void @mod_dest_before_copy() {
136639321564Skhei4; CHECK-LABEL: define void @mod_dest_before_copy() {
136739321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
136839321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
1369*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1370*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
137139321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
137239321564Skhei4; CHECK-NEXT:    store i32 13, ptr [[DEST]], align 4
1373*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
137439321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
1375*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
1376*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[DEST]])
1377*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
137839321564Skhei4; CHECK-NEXT:    ret void
137939321564Skhei4;
138039321564Skhei4  %src = alloca %struct.Foo, align 4
138139321564Skhei4  %dest = alloca %struct.Foo, align 4
138239321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
138339321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
138439321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
138539321564Skhei4  store i32 13, ptr %dest
138639321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
138739321564Skhei4
138839321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
138939321564Skhei4
139039321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
139139321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
139239321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
139339321564Skhei4  ret void
139439321564Skhei4}
139539321564Skhei4
139639321564Skhei4define void @mod_src_before_store_after_load() {
139739321564Skhei4; CHECK-LABEL: define void @mod_src_before_store_after_load() {
139839321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
139939321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
1400*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1401*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
140239321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
140339321564Skhei4; CHECK-NEXT:    store i32 13, ptr [[DEST]], align 4
1404*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
140539321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
140639321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 13, i32 13, i32 13 }, ptr [[SRC]], align 4
1407*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
1408*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[DEST]])
1409*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
141039321564Skhei4; CHECK-NEXT:    ret void
141139321564Skhei4;
141239321564Skhei4  %src = alloca %struct.Foo, align 4
141339321564Skhei4  %dest = alloca %struct.Foo, align 4
141439321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
141539321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
141639321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
141739321564Skhei4  store i32 13, ptr %dest
141839321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
141939321564Skhei4
142039321564Skhei4  %src.val = load %struct.Foo, ptr %src
142139321564Skhei4  store %struct.Foo { i32 13, i32 13, i32 13 }, ptr %src
142239321564Skhei4  store %struct.Foo %src.val, ptr %dest
142339321564Skhei4
142439321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
142539321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
142639321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
142739321564Skhei4  ret void
142839321564Skhei4}
142939321564Skhei4
143039321564Skhei4; Tests that the optimization isn't performed,
143139321564Skhei4; when the source may have mod and dest may have ref after the full copy.
143239321564Skhei4define void @src_mod_dest_ref_after_copy() {
143339321564Skhei4; CHECK-LABEL: define void @src_mod_dest_ref_after_copy() {
143439321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
143539321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
1436*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1437*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
143839321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
143939321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
144039321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 13, i32 13, i32 13 }, ptr [[SRC]], align 4
1441*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[DEST]])
1442*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
1443*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
144439321564Skhei4; CHECK-NEXT:    ret void
144539321564Skhei4;
144639321564Skhei4  %src = alloca %struct.Foo, align 4
144739321564Skhei4  %dest = alloca %struct.Foo, align 4
144839321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
144939321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
145039321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
145139321564Skhei4
145239321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
145339321564Skhei4
145439321564Skhei4  store %struct.Foo { i32 13, i32 13, i32 13 }, ptr %src
145539321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %dest)
145639321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
145739321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
145839321564Skhei4  ret void
145939321564Skhei4}
146039321564Skhei4
146139321564Skhei4; Tests that the optimization isn't performed.
146239321564Skhei4; Merging dest to src is no longer valid if conflicting Mod/Ref exist.
146339321564Skhei4define void @src_ref_dest_mod_after_copy() {
146439321564Skhei4; CHECK-LABEL: define void @src_ref_dest_mod_after_copy() {
146539321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
146639321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
1467*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1468*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
146939321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
147039321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
147139321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 13, i32 13, i32 13 }, ptr [[DEST]], align 4
1472*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
1473*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
1474*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
147539321564Skhei4; CHECK-NEXT:    ret void
147639321564Skhei4;
147739321564Skhei4  %src = alloca %struct.Foo, align 4
147839321564Skhei4  %dest = alloca %struct.Foo, align 4
147939321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
148039321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
148139321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
148239321564Skhei4
148339321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
148439321564Skhei4
148539321564Skhei4  store %struct.Foo { i32 13, i32 13, i32 13 }, ptr %dest
148639321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
148739321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
148839321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
148939321564Skhei4  ret void
149039321564Skhei4}
149139321564Skhei4
149239321564Skhei4; Tests that failure because alloca is modified through aliases, which requires recursive user ModRefChecks
149339321564Skhei4define void @dest_alias_mod_before_copy() {
149439321564Skhei4; CHECK-LABEL: define void @dest_alias_mod_before_copy() {
149539321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
149639321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
1497*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1498*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
149939321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
150039321564Skhei4; CHECK-NEXT:    [[DEST_ALIAS:%.*]] = getelementptr inbounds [[STRUCT_FOO]], ptr [[DEST]], i64 0, i32 1
150139321564Skhei4; CHECK-NEXT:    store i32 13, ptr [[DEST_ALIAS]], align 4
1502*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
150339321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
1504*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[DEST]])
1505*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
1506*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
150739321564Skhei4; CHECK-NEXT:    ret void
150839321564Skhei4;
150939321564Skhei4  %src = alloca %struct.Foo, align 4
151039321564Skhei4  %dest = alloca %struct.Foo, align 4
151139321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
151239321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
151339321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
151439321564Skhei4  %dest.alias = getelementptr inbounds %struct.Foo, ptr %dest, i64 0, i32 1
151539321564Skhei4  store i32 13, ptr %dest.alias
151639321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
151739321564Skhei4
151839321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
151939321564Skhei4
152039321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
152139321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
152239321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
152339321564Skhei4  ret void
152439321564Skhei4}
152539321564Skhei4
152639321564Skhei4; Tests that failure because alloca is modified through aliases, which requires recursive user ModRefChecks
152739321564Skhei4define void @alias_src_ref_dest_mod_after_copy() {
152839321564Skhei4; CHECK-LABEL: define void @alias_src_ref_dest_mod_after_copy() {
152939321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
153039321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
1531*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1532*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
153339321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
1534*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
153539321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
153639321564Skhei4; CHECK-NEXT:    [[DEST_ALIAS:%.*]] = getelementptr inbounds [[STRUCT_FOO]], ptr [[DEST]], i64 0, i32 1
153739321564Skhei4; CHECK-NEXT:    store i32 13, ptr [[DEST_ALIAS]], align 4
1538*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
1539*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
1540*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
154139321564Skhei4; CHECK-NEXT:    ret void
154239321564Skhei4;
154339321564Skhei4  %src = alloca %struct.Foo, align 4
154439321564Skhei4  %dest = alloca %struct.Foo, align 4
154539321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
154639321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
154739321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
154839321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
154939321564Skhei4
155039321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
155139321564Skhei4
155239321564Skhei4  %dest.alias = getelementptr inbounds %struct.Foo, ptr %dest, i64 0, i32 1
155339321564Skhei4  store i32 13, ptr %dest.alias
155439321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %src)
155539321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
155639321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
155739321564Skhei4  ret void
155839321564Skhei4}
155939321564Skhei4
1560e0911b98Skhei4; Tests that the optimization isn't performed when the source and destination
1561c4d37c35Skhei4; have mod ref conflict on bb2.
1562c4d37c35Skhei4define void @multi_bb_dataflow_conflict(i1 %b) {
1563c4d37c35Skhei4; CHECK-LABEL: define void @multi_bb_dataflow_conflict
1564e0911b98Skhei4; CHECK-SAME: (i1 [[B:%.*]]) {
1565e0911b98Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
1566e0911b98Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
1567*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1568*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
1569e0911b98Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
1570*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
1571e0911b98Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
1572e0911b98Skhei4; CHECK-NEXT:    br i1 [[B]], label [[BB0:%.*]], label [[BB1:%.*]]
1573e0911b98Skhei4; CHECK:       bb0:
1574*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
1575e0911b98Skhei4; CHECK-NEXT:    br label [[BB2:%.*]]
1576e0911b98Skhei4; CHECK:       bb1:
1577*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[DEST]])
1578e0911b98Skhei4; CHECK-NEXT:    br label [[BB2]]
1579e0911b98Skhei4; CHECK:       bb2:
1580*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP4:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[DEST]])
1581*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
1582*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
1583e0911b98Skhei4; CHECK-NEXT:    ret void
1584e0911b98Skhei4;
1585e0911b98Skhei4  %src = alloca %struct.Foo, align 4
1586e0911b98Skhei4  %dest = alloca %struct.Foo, align 4
1587e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
1588e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
1589e0911b98Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
1590e0911b98Skhei4  %1 = call i32 @use_nocapture(ptr noundef nocapture %src)
1591e0911b98Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
1592e0911b98Skhei4  br i1 %b, label %bb0, label %bb1
1593e0911b98Skhei4
1594e0911b98Skhei4bb0:
1595e0911b98Skhei4  %2 = call i32 @use_nocapture(ptr noundef nocapture %src)
1596e0911b98Skhei4  br label %bb2
1597e0911b98Skhei4
1598e0911b98Skhei4bb1:
1599e0911b98Skhei4  %3 = call i32 @use_nocapture(ptr noundef nocapture %dest)
1600e0911b98Skhei4  br label %bb2
1601e0911b98Skhei4
1602e0911b98Skhei4bb2:
1603c4d37c35Skhei4  %4 = call i32 @use_nocapture(ptr noundef nocapture %dest)
1604e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
1605e0911b98Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
1606e0911b98Skhei4  ret void
1607e0911b98Skhei4}
1608e0911b98Skhei4
1609e0911b98Skhei4; Tests that failure because after copy mod could be before copy on loop.
1610e0911b98Skhei4define void @multi_bb_loop_dest_mod_before_copy(i32 %n) {
1611e0911b98Skhei4; CHECK-LABEL: define void @multi_bb_loop_dest_mod_before_copy
1612e0911b98Skhei4; CHECK-SAME: (i32 [[N:%.*]]) {
1613e0911b98Skhei4; CHECK-NEXT:  entry:
1614e0911b98Skhei4; CHECK-NEXT:    [[NLT1:%.*]] = icmp slt i32 [[N]], 1
1615e0911b98Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 8
1616e0911b98Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 8
1617*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1618*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[DEST]])
1619e0911b98Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 0, i32 1, i32 42 }, ptr [[SRC]], align 4
1620e0911b98Skhei4; CHECK-NEXT:    br i1 [[NLT1]], label [[LOOP_EXIT:%.*]], label [[LOOP_BODY:%.*]]
1621e0911b98Skhei4; CHECK:       loop_body:
1622e0911b98Skhei4; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[NEW_I:%.*]], [[LOOP_BODY]] ], [ 1, [[ENTRY:%.*]] ]
1623e0911b98Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[DEST]], ptr align 8 [[SRC]], i64 12, i1 false)
1624e0911b98Skhei4; CHECK-NEXT:    [[NEW_I]] = add i32 [[I]], 1
1625e0911b98Skhei4; CHECK-NEXT:    store i32 [[NEW_I]], ptr [[DEST]], align 4
1626e0911b98Skhei4; CHECK-NEXT:    [[IGTN:%.*]] = icmp sgt i32 [[NEW_I]], [[N]]
1627e0911b98Skhei4; CHECK-NEXT:    br i1 [[IGTN]], label [[LOOP_EXIT]], label [[LOOP_BODY]]
1628e0911b98Skhei4; CHECK:       loop_exit:
1629e0911b98Skhei4; CHECK-NEXT:    ret void
1630e0911b98Skhei4;
1631e0911b98Skhei4entry:
1632e0911b98Skhei4  %nlt1 = icmp slt i32 %n, 1
1633e0911b98Skhei4  %src = alloca %struct.Foo, align 8
1634e0911b98Skhei4  %dest = alloca %struct.Foo, align 8
1635e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
1636e0911b98Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %dest)
1637e0911b98Skhei4  store %struct.Foo { i32 0, i32 1, i32 42 }, ptr %src
1638e0911b98Skhei4  br i1 %nlt1, label %loop_exit, label %loop_body
1639e0911b98Skhei4
1640e0911b98Skhei4loop_body:
1641e0911b98Skhei4  %i = phi i32 [ %new_i, %loop_body ], [ 1, %entry ]
1642e0911b98Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %dest, ptr align 8 %src, i64 12, i1 false)
1643e0911b98Skhei4  %new_i = add i32 %i, 1
1644e0911b98Skhei4  store i32 %new_i, ptr %dest
1645e0911b98Skhei4  %igtn = icmp sgt i32 %new_i, %n
1646e0911b98Skhei4  br i1 %igtn, label %loop_exit, label %loop_body
1647e0911b98Skhei4
1648e0911b98Skhei4loop_exit:
1649e0911b98Skhei4  ret void
1650e0911b98Skhei4}
1651e0911b98Skhei4
165239321564Skhei4; Tests that failure because partial-sized lifetimes are counted as mod.
165339321564Skhei4define void @partial_lifetime() {
165439321564Skhei4; CHECK-LABEL: define void @partial_lifetime() {
165539321564Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO:%.*]], align 4
165639321564Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO]], align 4
1657*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 12, ptr captures(none) [[SRC]])
1658*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 3, ptr captures(none) [[DEST]])
165939321564Skhei4; CHECK-NEXT:    store [[STRUCT_FOO]] { i32 10, i32 20, i32 30 }, ptr [[SRC]], align 4
1660*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @use_nocapture(ptr captures(none) [[SRC]])
166139321564Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DEST]], ptr align 4 [[SRC]], i64 12, i1 false)
1662*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 3, ptr captures(none) [[SRC]])
1663*29441e4fSNikita Popov; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @use_nocapture(ptr captures(none) [[DEST]])
1664*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[SRC]])
1665*29441e4fSNikita Popov; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 12, ptr captures(none) [[DEST]])
166639321564Skhei4; CHECK-NEXT:    ret void
166739321564Skhei4;
166839321564Skhei4  %src = alloca %struct.Foo, align 4
166939321564Skhei4  %dest = alloca %struct.Foo, align 4
167039321564Skhei4  call void @llvm.lifetime.start.p0(i64 12, ptr nocapture %src)
167139321564Skhei4  call void @llvm.lifetime.start.p0(i64 3, ptr nocapture %dest)
167239321564Skhei4  store %struct.Foo { i32 10, i32 20, i32 30 }, ptr %src
167339321564Skhei4  %1 = call i32 @use_nocapture(ptr nocapture %src)
167439321564Skhei4
167539321564Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr align 4 %dest, ptr align 4 %src, i64 12, i1 false)
167639321564Skhei4
167739321564Skhei4  call void @llvm.lifetime.end.p0(i64 3, ptr nocapture %src)
167839321564Skhei4  %2 = call i32 @use_nocapture(ptr nocapture %dest)
167939321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %src)
168039321564Skhei4  call void @llvm.lifetime.end.p0(i64 12, ptr nocapture %dest)
168139321564Skhei4  ret void
168239321564Skhei4}
1683a92e1971Skhei4
1684a92e1971Skhei4; Do not merge or crash if the different block user comes first.
1685a92e1971Skhei4define void @crash_store63851(i1 %b) {
1686a92e1971Skhei4; CHECK-LABEL: define void @crash_store63851
1687a92e1971Skhei4; CHECK-SAME: (i1 [[B:%.*]]) {
1688a92e1971Skhei4; CHECK-NEXT:    [[DEST:%.*]] = alloca [[STRUCT_FOO:%.*]], align 8
1689a92e1971Skhei4; CHECK-NEXT:    [[SRC:%.*]] = alloca [[STRUCT_FOO]], align 8
1690a92e1971Skhei4; CHECK-NEXT:    store i32 0, ptr [[DEST]], align 4
1691a92e1971Skhei4; CHECK-NEXT:    br i1 [[B]], label [[THEN:%.*]], label [[ELSE:%.*]]
1692a92e1971Skhei4; CHECK:       then:
1693*29441e4fSNikita Popov; CHECK-NEXT:    [[T:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
1694a92e1971Skhei4; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[DEST]], ptr [[SRC]], i64 12, i1 false)
1695*29441e4fSNikita Popov; CHECK-NEXT:    [[T3:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[SRC]])
1696*29441e4fSNikita Popov; CHECK-NEXT:    [[T4:%.*]] = call i32 @use_nocapture(ptr noundef captures(none) [[DEST]])
1697a92e1971Skhei4; CHECK-NEXT:    br label [[ELSE]]
1698a92e1971Skhei4; CHECK:       else:
1699a92e1971Skhei4; CHECK-NEXT:    ret void
1700a92e1971Skhei4;
1701a92e1971Skhei4  %dest = alloca %struct.Foo, align 8
1702a92e1971Skhei4  %src = alloca %struct.Foo, align 8
1703a92e1971Skhei4  store i32 0, ptr %dest, align 4
1704a92e1971Skhei4  br i1 %b, label %then, label %else
1705a92e1971Skhei4
1706a92e1971Skhei4then:                                             ; preds = %entry
1707a92e1971Skhei4  %t = call i32 @use_nocapture(ptr nocapture noundef %src)
1708a92e1971Skhei4  call void @llvm.memcpy.p0.p0.i64(ptr %dest, ptr %src, i64 12, i1 false)
1709a92e1971Skhei4  %t3 = call i32 @use_nocapture(ptr nocapture noundef %src)
1710a92e1971Skhei4  %t4 = call i32 @use_nocapture(ptr nocapture noundef %dest)
1711a92e1971Skhei4  br label %else
1712a92e1971Skhei4
1713a92e1971Skhei4else:                                             ; preds = %then, %entry
1714a92e1971Skhei4  ret void
1715a92e1971Skhei4
1716a92e1971Skhei4  uselistorder ptr %dest, { 1, 2, 0 }
1717a92e1971Skhei4}
1718