1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
4 target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
6 declare void @readnone_may_throw() readnone
8 declare void @use(i32 *)
10 ; Tests where the pointer/object is accessible after the function returns.
12 ; Cannot remove the store from the entry block, because the call in bb2 may throw.
13 define void @accessible_after_return_1(i32* noalias %P, i1 %c1) {
14 ; CHECK-LABEL: @accessible_after_return_1(
15 ; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4
16 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
18 ; CHECK-NEXT: store i32 0, i32* [[P]], align 4
19 ; CHECK-NEXT: br label [[BB5:%.*]]
21 ; CHECK-NEXT: call void @readnone_may_throw()
22 ; CHECK-NEXT: store i32 3, i32* [[P]], align 4
23 ; CHECK-NEXT: br label [[BB5]]
25 ; CHECK-NEXT: call void @use(i32* [[P]])
26 ; CHECK-NEXT: ret void
29 br i1 %c1, label %bb1, label %bb2
36 call void @readnone_may_throw()
41 call void @use(i32* %P)
45 ; Cannot remove the store from the entry block, because the call in bb3 may throw.
46 define void @accessible_after_return6(i32* %P, i1 %c.1, i1 %c.2) {
47 ; CHECK-LABEL: @accessible_after_return6(
49 ; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
50 ; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
52 ; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
54 ; CHECK-NEXT: store i32 1, i32* [[P]], align 4
55 ; CHECK-NEXT: ret void
57 ; CHECK-NEXT: call void @readnone_may_throw()
58 ; CHECK-NEXT: store i32 2, i32* [[P]], align 4
59 ; CHECK-NEXT: ret void
61 ; CHECK-NEXT: store i32 3, i32* [[P]], align 4
62 ; CHECK-NEXT: ret void
66 br i1 %c.1, label %bb1, label %bb2
69 br i1 %c.2, label %bb3, label %bb4
76 call void @readnone_may_throw()
85 ; Tests where the pointer/object is *NOT* accessible after the function returns.
87 ; The store in the entry block can be eliminated, because it is overwritten
88 ; on all paths to the exit. As the location is not visible to the caller, the
89 ; call in bb2 (which may throw) can be ignored.
90 define void @alloca_1(i1 %c1) {
91 ; CHECK-LABEL: @alloca_1(
93 ; CHECK-NEXT: [[P:%.*]] = alloca i32
94 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
96 ; CHECK-NEXT: store i32 0, i32* [[P]], align 4
97 ; CHECK-NEXT: br label [[BB5:%.*]]
99 ; CHECK-NEXT: call void @readnone_may_throw()
100 ; CHECK-NEXT: store i32 3, i32* [[P]], align 4
101 ; CHECK-NEXT: br label [[BB5]]
103 ; CHECK-NEXT: call void @use(i32* [[P]])
104 ; CHECK-NEXT: ret void
109 br i1 %c1, label %bb1, label %bb2
116 call void @readnone_may_throw()
121 call void @use(i32* %P)
125 ; The store in the entry block can be eliminated, because it is overwritten
126 ; on all paths to the exit. As the location is not visible to the caller, the
127 ; call in bb3 (which may throw) can be ignored.
128 define void @alloca_2(i1 %c.1, i1 %c.2) {
129 ; CHECK-LABEL: @alloca_2(
130 ; CHECK-NEXT: [[P:%.*]] = alloca i32
131 ; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
133 ; CHECK-NEXT: store i32 0, i32* [[P]], align 4
134 ; CHECK-NEXT: br label [[BB5:%.*]]
136 ; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
138 ; CHECK-NEXT: call void @readnone_may_throw()
139 ; CHECK-NEXT: store i32 3, i32* [[P]], align 4
140 ; CHECK-NEXT: br label [[BB5]]
142 ; CHECK-NEXT: store i32 5, i32* [[P]], align 4
143 ; CHECK-NEXT: br label [[BB5]]
145 ; CHECK-NEXT: call void @use(i32* [[P]])
146 ; CHECK-NEXT: ret void
150 br i1 %c.1, label %bb1, label %bb2
157 br i1 %c.2, label %bb3, label %bb4
160 call void @readnone_may_throw()
169 call void @use(i32* %P)