1; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
2
3declare noalias i8* @malloc(i64) "malloc-like"
4
5declare void @foo()
6declare void @bar(i8*)
7
8define void @test() {
9  %obj = call i8* @malloc(i64 8)
10  store i8 0, i8* %obj
11  ; don't remove store. %obj should be treated like it will be read by the @foo.
12  ; CHECK: store i8 0, i8* %obj
13  call void @foo() ["deopt" (i8* %obj)]
14  ret void
15}
16
17define void @test1() {
18  %obj = call i8* @malloc(i64 8)
19  store i8 0, i8* %obj
20  ; CHECK: store i8 0, i8* %obj
21  call void @bar(i8* nocapture %obj)
22  ret void
23}
24
25define void @test2() {
26  %obj = call i8* @malloc(i64 8)
27  store i8 0, i8* %obj
28  ; CHECK-NOT: store i8 0, i8* %obj
29  call void @foo()
30  ret void
31}
32
33define void @test3() {
34  ; CHECK-LABEL: @test3(
35  %s = alloca i64
36  ; Verify that this first store is not considered killed by the second one
37  ; since it could be observed from the deopt continuation.
38  ; CHECK: store i64 1, i64* %s
39  store i64 1, i64* %s
40  call void @foo() [ "deopt"(i64* %s) ]
41  store i64 0, i64* %s
42  ret void
43}
44
45declare noalias i8* @calloc(i64, i64)
46
47define void @test4() {
48; CHECK-LABEL: @test4
49  %local_obj = call i8* @calloc(i64 1, i64 4)
50  call void @foo() ["deopt" (i8* %local_obj)]
51  store i8 0, i8* %local_obj, align 4
52  ; CHECK-NOT: store i8 0, i8* %local_obj, align 4
53  call void @bar(i8* nocapture %local_obj)
54  ret void
55}
56