1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s
4 declare void @bar() nounwind
6 define i32 @test1(ptr %a, i32 %b, ptr %c, i32 %d) nounwind {
7 ; CHECK-LABEL: define i32 @test1
8 ; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR0:[0-9]+]] {
10 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
11 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
13 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
14 ; CHECK-NEXT: br label [[IF_END7:%.*]]
16 ; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
17 ; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[TOBOOL3]], true
18 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
19 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
20 ; CHECK-NEXT: br label [[IF_END7]]
22 ; CHECK-NEXT: [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ [[C]], [[IF_ELSE]] ]
23 ; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[X_0]], align 4
24 ; CHECK-NEXT: ret i32 [[TMP9]]
27 %tobool = icmp eq i32 %b, 0
28 br i1 %tobool, label %if.else, label %if.then
30 if.then: ; preds = %entry
31 tail call void @bar() nounwind
34 if.else: ; preds = %entry
35 %tobool3 = icmp eq i32 %d, 0
36 br i1 %tobool3, label %if.end7, label %if.then4
38 if.then4: ; preds = %if.else
39 tail call void @bar() nounwind
42 if.end7: ; preds = %if.else, %if.then4, %if.then
43 %x.0 = phi ptr [ %a, %if.then ], [ %c, %if.then4 ], [ null, %if.else ]
44 %tmp9 = load i32, ptr %x.0
48 define i32 @test1_no_null_opt(ptr %a, i32 %b, ptr %c, i32 %d) nounwind #0 {
49 ; CHECK-LABEL: define i32 @test1_no_null_opt
50 ; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR1:[0-9]+]] {
52 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
53 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
55 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
56 ; CHECK-NEXT: br label [[IF_END7:%.*]]
58 ; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
59 ; CHECK-NEXT: br i1 [[TOBOOL3]], label [[IF_END7]], label [[IF_THEN4:%.*]]
61 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
62 ; CHECK-NEXT: br label [[IF_END7]]
64 ; CHECK-NEXT: [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ [[C]], [[IF_THEN4]] ], [ null, [[IF_ELSE]] ]
65 ; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[X_0]], align 4
66 ; CHECK-NEXT: ret i32 [[TMP9]]
69 %tobool = icmp eq i32 %b, 0
70 br i1 %tobool, label %if.else, label %if.then
72 if.then: ; preds = %entry
73 tail call void @bar() nounwind
76 if.else: ; preds = %entry
77 %tobool3 = icmp eq i32 %d, 0
78 br i1 %tobool3, label %if.end7, label %if.then4
80 if.then4: ; preds = %if.else
81 tail call void @bar() nounwind
84 if.end7: ; preds = %if.else, %if.then4, %if.then
85 %x.0 = phi ptr [ %a, %if.then ], [ %c, %if.then4 ], [ null, %if.else ]
86 %tmp9 = load i32, ptr %x.0
90 define i32 @test2(ptr %a, i32 %b, ptr %c, i32 %d) nounwind {
91 ; CHECK-LABEL: define i32 @test2
92 ; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR0]] {
94 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
95 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
97 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
98 ; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[A]], align 4
99 ; CHECK-NEXT: ret i32 [[TMP9]]
101 ; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
102 ; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[TOBOOL3]], true
103 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
104 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
105 ; CHECK-NEXT: unreachable
108 %tobool = icmp eq i32 %b, 0
109 br i1 %tobool, label %if.else, label %if.then
111 if.then: ; preds = %entry
112 tail call void @bar() nounwind
115 if.else: ; preds = %entry
116 %tobool3 = icmp eq i32 %d, 0
117 br i1 %tobool3, label %if.end7, label %if.then4
119 if.then4: ; preds = %if.else
120 tail call void @bar() nounwind
123 if.end7: ; preds = %if.else, %if.then4, %if.then
124 %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
125 %tmp9 = load i32, ptr %x.0
129 define i32 @test2_no_null_opt(ptr %a, i32 %b, ptr %c, i32 %d) nounwind #0 {
130 ; CHECK-LABEL: define i32 @test2_no_null_opt
131 ; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR1]] {
133 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
134 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
136 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
137 ; CHECK-NEXT: br label [[IF_END7:%.*]]
139 ; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
140 ; CHECK-NEXT: br i1 [[TOBOOL3]], label [[IF_END7]], label [[IF_THEN4:%.*]]
142 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
143 ; CHECK-NEXT: br label [[IF_END7]]
145 ; CHECK-NEXT: [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ null, [[IF_THEN4]] ], [ null, [[IF_ELSE]] ]
146 ; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[X_0]], align 4
147 ; CHECK-NEXT: ret i32 [[TMP9]]
150 %tobool = icmp eq i32 %b, 0
151 br i1 %tobool, label %if.else, label %if.then
153 if.then: ; preds = %entry
154 tail call void @bar() nounwind
157 if.else: ; preds = %entry
158 %tobool3 = icmp eq i32 %d, 0
159 br i1 %tobool3, label %if.end7, label %if.then4
161 if.then4: ; preds = %if.else
162 tail call void @bar() nounwind
165 if.end7: ; preds = %if.else, %if.then4, %if.then
166 %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
167 %tmp9 = load i32, ptr %x.0
171 define i32 @test3(ptr %a, i32 %b, ptr %c, i32 %d) nounwind {
172 ; CHECK-LABEL: define i32 @test3
173 ; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR0]] {
175 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
176 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
178 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
179 ; CHECK-NEXT: br label [[IF_END7:%.*]]
181 ; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
182 ; CHECK-NEXT: br i1 [[TOBOOL3]], label [[IF_END7]], label [[IF_THEN4:%.*]]
184 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
185 ; CHECK-NEXT: br label [[IF_END7]]
187 ; CHECK-NEXT: [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ null, [[IF_THEN4]] ], [ null, [[IF_ELSE]] ]
188 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
189 ; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[X_0]], align 4
190 ; CHECK-NEXT: ret i32 [[TMP9]]
193 %tobool = icmp eq i32 %b, 0
194 br i1 %tobool, label %if.else, label %if.then
196 if.then: ; preds = %entry
197 tail call void @bar() nounwind
200 if.else: ; preds = %entry
201 %tobool3 = icmp eq i32 %d, 0
202 br i1 %tobool3, label %if.end7, label %if.then4
204 if.then4: ; preds = %if.else
205 tail call void @bar() nounwind
208 if.end7: ; preds = %if.else, %if.then4, %if.then
209 %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
210 tail call void @bar() nounwind
211 %tmp9 = load i32, ptr %x.0
215 define i32 @test3_no_null_opt(ptr %a, i32 %b, ptr %c, i32 %d) nounwind #0 {
216 ; CHECK-LABEL: define i32 @test3_no_null_opt
217 ; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR1]] {
219 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
220 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
222 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
223 ; CHECK-NEXT: br label [[IF_END7:%.*]]
225 ; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
226 ; CHECK-NEXT: br i1 [[TOBOOL3]], label [[IF_END7]], label [[IF_THEN4:%.*]]
228 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
229 ; CHECK-NEXT: br label [[IF_END7]]
231 ; CHECK-NEXT: [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ null, [[IF_THEN4]] ], [ null, [[IF_ELSE]] ]
232 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
233 ; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[X_0]], align 4
234 ; CHECK-NEXT: ret i32 [[TMP9]]
237 %tobool = icmp eq i32 %b, 0
238 br i1 %tobool, label %if.else, label %if.then
240 if.then: ; preds = %entry
241 tail call void @bar() nounwind
244 if.else: ; preds = %entry
245 %tobool3 = icmp eq i32 %d, 0
246 br i1 %tobool3, label %if.end7, label %if.then4
248 if.then4: ; preds = %if.else
249 tail call void @bar() nounwind
252 if.end7: ; preds = %if.else, %if.then4, %if.then
253 %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
254 tail call void @bar() nounwind
255 %tmp9 = load i32, ptr %x.0
259 define i32 @test4(ptr %a, i32 %b, ptr %c, i32 %d) nounwind {
260 ; CHECK-LABEL: define i32 @test4
261 ; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR0]] {
263 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
264 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
266 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
267 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[A]], i32 10
268 ; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[GEP]], align 4
269 ; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], 1
270 ; CHECK-NEXT: store i32 [[TMP10]], ptr [[GEP]], align 4
271 ; CHECK-NEXT: ret i32 [[TMP9]]
273 ; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
274 ; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[TOBOOL3]], true
275 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
276 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
277 ; CHECK-NEXT: unreachable
280 %tobool = icmp eq i32 %b, 0
281 br i1 %tobool, label %if.else, label %if.then
283 if.then: ; preds = %entry
284 tail call void @bar() nounwind
287 if.else: ; preds = %entry
288 %tobool3 = icmp eq i32 %d, 0
289 br i1 %tobool3, label %if.end7, label %if.then4
291 if.then4: ; preds = %if.else
292 tail call void @bar() nounwind
295 if.end7: ; preds = %if.else, %if.then4, %if.then
296 %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
297 %gep = getelementptr i32, ptr %x.0, i32 10
298 %tmp9 = load i32, ptr %gep
299 %tmp10 = or i32 %tmp9, 1
300 store i32 %tmp10, ptr %gep
304 define i32 @test4_no_null_opt(ptr %a, i32 %b, ptr %c, i32 %d) nounwind #0 {
305 ; CHECK-LABEL: define i32 @test4_no_null_opt
306 ; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]], ptr [[C:%.*]], i32 [[D:%.*]]) #[[ATTR1]] {
308 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[B]], 0
309 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
311 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
312 ; CHECK-NEXT: br label [[IF_END7:%.*]]
314 ; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[D]], 0
315 ; CHECK-NEXT: br i1 [[TOBOOL3]], label [[IF_END7]], label [[IF_THEN4:%.*]]
317 ; CHECK-NEXT: tail call void @bar() #[[ATTR0]]
318 ; CHECK-NEXT: br label [[IF_END7]]
320 ; CHECK-NEXT: [[X_0:%.*]] = phi ptr [ [[A]], [[IF_THEN]] ], [ null, [[IF_THEN4]] ], [ null, [[IF_ELSE]] ]
321 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[X_0]], i32 10
322 ; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[GEP]], align 4
323 ; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], 1
324 ; CHECK-NEXT: store i32 [[TMP10]], ptr [[GEP]], align 4
325 ; CHECK-NEXT: ret i32 [[TMP9]]
328 %tobool = icmp eq i32 %b, 0
329 br i1 %tobool, label %if.else, label %if.then
331 if.then: ; preds = %entry
332 tail call void @bar() nounwind
335 if.else: ; preds = %entry
336 %tobool3 = icmp eq i32 %d, 0
337 br i1 %tobool3, label %if.end7, label %if.then4
339 if.then4: ; preds = %if.else
340 tail call void @bar() nounwind
343 if.end7: ; preds = %if.else, %if.then4, %if.then
344 %x.0 = phi ptr [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
345 %gep = getelementptr i32, ptr %x.0, i32 10
346 %tmp9 = load i32, ptr %gep
347 %tmp10 = or i32 %tmp9, 1
348 store i32 %tmp10, ptr %gep
352 attributes #0 = { null_pointer_is_valid }