1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -basic-aa -dse -S %s | FileCheck %s
4 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
6 ; Test case for PR16520. The store in %if.then is dead, because the same value
7 ; has been stored earlier to the same location.
8 define void @test1_pr16520(i1 %b, i8* nocapture %r) {
9 ; CHECK-LABEL: @test1_pr16520(
11 ; CHECK-NEXT: store i8 1, i8* [[R:%.*]], align 1
12 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
14 ; CHECK-NEXT: store i8 1, i8* [[R]], align 1
15 ; CHECK-NEXT: tail call void @fn_mayread_or_clobber()
16 ; CHECK-NEXT: br label [[IF_END:%.*]]
18 ; CHECK-NEXT: tail call void @fn_mayread_or_clobber()
19 ; CHECK-NEXT: br label [[IF_END]]
21 ; CHECK-NEXT: ret void
24 store i8 1, i8* %r, align 1
25 br i1 %b, label %if.then, label %if.else
27 if.then: ; preds = %entry
28 store i8 1, i8* %r, align 1
29 tail call void @fn_mayread_or_clobber()
32 if.else: ; preds = %entry
33 tail call void @fn_mayread_or_clobber()
36 if.end: ; preds = %if.else, %if.then
40 declare void @fn_mayread_or_clobber()
43 declare void @fn_readonly() readonly
45 define void @test2(i1 %b, i8* nocapture %r) {
46 ; CHECK-LABEL: @test2(
48 ; CHECK-NEXT: store i8 1, i8* [[R:%.*]], align 1
49 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
51 ; CHECK-NEXT: tail call void @fn_readonly()
52 ; CHECK-NEXT: br label [[IF_END:%.*]]
54 ; CHECK-NEXT: tail call void @fn_readonly()
55 ; CHECK-NEXT: br label [[IF_END]]
57 ; CHECK-NEXT: store i8 1, i8* [[R]], align 1
58 ; CHECK-NEXT: ret void
61 store i8 1, i8* %r, align 1
62 br i1 %b, label %if.then, label %if.else
64 if.then: ; preds = %entry
65 tail call void @fn_readonly()
68 if.else: ; preds = %entry
69 tail call void @fn_readonly()
72 if.end: ; preds = %if.else, %if.then
73 store i8 1, i8* %r, align 1
77 define void @test3(i1 %b, i8* nocapture %r) {
78 ; CHECK-LABEL: @test3(
80 ; CHECK-NEXT: store i8 1, i8* [[R:%.*]], align 1
81 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
83 ; CHECK-NEXT: tail call void @fn_mayread_or_clobber()
84 ; CHECK-NEXT: br label [[IF_END:%.*]]
86 ; CHECK-NEXT: tail call void @fn_readonly()
87 ; CHECK-NEXT: br label [[IF_END]]
89 ; CHECK-NEXT: store i8 1, i8* [[R]], align 1
90 ; CHECK-NEXT: ret void
93 store i8 1, i8* %r, align 1
94 br i1 %b, label %if.then, label %if.else
96 if.then: ; preds = %entry
97 tail call void @fn_mayread_or_clobber()
100 if.else: ; preds = %entry
101 tail call void @fn_readonly()
104 if.end: ; preds = %if.else, %if.then
105 store i8 1, i8* %r, align 1
109 define void @test4(i1 %b, i8* nocapture %r) {
110 ; CHECK-LABEL: @test4(
112 ; CHECK-NEXT: store i8 1, i8* [[R:%.*]], align 1
113 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
115 ; CHECK-NEXT: tail call void @fn_readonly()
116 ; CHECK-NEXT: br label [[IF_END:%.*]]
118 ; CHECK-NEXT: tail call void @fn_mayread_or_clobber()
119 ; CHECK-NEXT: br label [[IF_END]]
121 ; CHECK-NEXT: store i8 1, i8* [[R]], align 1
122 ; CHECK-NEXT: ret void
125 store i8 1, i8* %r, align 1
126 br i1 %b, label %if.then, label %if.else
128 if.then: ; preds = %entry
129 tail call void @fn_readonly()
132 if.else: ; preds = %entry
133 tail call void @fn_mayread_or_clobber()
136 if.end: ; preds = %if.else, %if.then
137 store i8 1, i8* %r, align 1
141 define void @test5(i1 %b, i8* nocapture %r) {
142 ; CHECK-LABEL: @test5(
144 ; CHECK-NEXT: store i8 1, i8* [[R:%.*]], align 1
145 ; CHECK-NEXT: br i1 [[B:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
147 ; CHECK-NEXT: tail call void @fn_readonly()
148 ; CHECK-NEXT: br label [[IF_END:%.*]]
150 ; CHECK-NEXT: tail call void @fn_mayread_or_clobber()
151 ; CHECK-NEXT: br label [[IF_END]]
153 ; CHECK-NEXT: store i8 1, i8* [[R]], align 1
154 ; CHECK-NEXT: ret void
157 store i8 1, i8* %r, align 1
158 br i1 %b, label %if.then, label %if.else
160 if.then: ; preds = %entry
161 tail call void @fn_readonly()
164 if.else: ; preds = %entry
165 tail call void @fn_mayread_or_clobber()
168 if.end: ; preds = %if.else, %if.then
169 store i8 1, i8* %r, align 1
173 declare i1 @cond() readnone
175 define void @test6(i32* noalias %P) {
176 ; CHECK-LABEL: @test6(
178 ; CHECK-NEXT: br label [[FOR_HEADER:%.*]]
180 ; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4
181 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
182 ; CHECK-NEXT: br i1 [[C1]], label [[FOR_BODY:%.*]], label [[END:%.*]]
184 ; CHECK-NEXT: store i32 1, i32* [[P]], align 4
185 ; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[P]], align 4
186 ; CHECK-NEXT: br label [[FOR_HEADER]]
188 ; CHECK-NEXT: store i32 3, i32* [[P]], align 4
189 ; CHECK-NEXT: ret void
195 store i32 1, i32* %P, align 4
196 %c1 = call i1 @cond()
197 br i1 %c1, label %for.body, label %end
200 store i32 1, i32* %P, align 4
201 %lv = load i32, i32* %P
205 store i32 3, i32* %P, align 4
209 ; Make sure the store in %bb3 can be eliminated in the presences of early returns.
210 define void @test7(i32* noalias %P) {
211 ; CHECK-LABEL: @test7(
212 ; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
213 ; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
215 ; CHECK-NEXT: br label [[BB3:%.*]]
217 ; CHECK-NEXT: ret void
219 ; CHECK-NEXT: store i32 0, i32* [[P]], align 4
220 ; CHECK-NEXT: ret void
223 br i1 true, label %bb1, label %bb2
233 ; Make sure the store in %bb3 won't be eliminated because it may be clobbered before.
234 define void @test8(i32* noalias %P) {
235 ; CHECK-LABEL: @test8(
236 ; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
237 ; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
239 ; CHECK-NEXT: call void @fn_mayread_or_clobber()
240 ; CHECK-NEXT: br label [[BB3:%.*]]
242 ; CHECK-NEXT: ret void
244 ; CHECK-NEXT: store i32 0, i32* [[P]], align 4
245 ; CHECK-NEXT: ret void
248 br i1 true, label %bb1, label %bb2
250 call void @fn_mayread_or_clobber()
259 ; Make sure the store in %bb3 will be eliminated because only the early exit path
261 define void @test9(i32* noalias %P) {
262 ; CHECK-LABEL: @test9(
263 ; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
264 ; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
266 ; CHECK-NEXT: br label [[BB3:%.*]]
268 ; CHECK-NEXT: call void @fn_mayread_or_clobber()
269 ; CHECK-NEXT: ret void
271 ; CHECK-NEXT: store i32 0, i32* [[P]], align 4
272 ; CHECK-NEXT: ret void
275 br i1 true, label %bb1, label %bb2
279 call void @fn_mayread_or_clobber()