Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / UnreachableEliminate.ll
blob5ba43c055f9be1235571be6ec911a7be6c9a3be1
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
2 ; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1  -S | FileCheck %s
4 define void @test1(i1 %C, ptr %BP) {
5 ; CHECK-LABEL: @test1(
6 ; CHECK-NEXT:  entry:
7 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[C:%.*]], true
8 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
9 ; CHECK-NEXT:    ret void
11 entry:
12   br i1 %C, label %T, label %F
14   store i1 %C, ptr %BP
15   unreachable
17   ret void
20 define void @test2() personality ptr @__gxx_personality_v0 {
21 ; CHECK-LABEL: @test2(
22 ; CHECK-NEXT:  entry:
23 ; CHECK-NEXT:    call void @test2() #[[ATTR3:[0-9]+]]
24 ; CHECK-NEXT:    ret void
26 entry:
27   invoke void @test2( )
28   to label %N unwind label %U
30   %res = landingpad { ptr }
31   cleanup
32   unreachable
34   ret void
37 declare i32 @__gxx_personality_v0(...)
39 define i32 @test3(i32 %v) {
40 ; CHECK-LABEL: @test3(
41 ; CHECK-NEXT:  entry:
42 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[V:%.*]], 2
43 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[COND]], i32 2, i32 1
44 ; CHECK-NEXT:    ret i32 [[SPEC_SELECT]]
46 entry:
47   switch i32 %v, label %default [
48   i32 1, label %U
49   i32 2, label %T
50   ]
51 default:
52   ret i32 1
54   unreachable
56   ret i32 2
60 ;; We can either convert the following control-flow to a select or remove the
61 ;; unreachable control flow because of the undef store of null. Make sure we do
62 ;; the latter.
64 define void @test5(i1 %cond, ptr %ptr) {
65 ; CHECK-LABEL: @test5(
66 ; CHECK-NEXT:  entry:
67 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[COND:%.*]], true
68 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
69 ; CHECK-NEXT:    store i8 2, ptr [[PTR:%.*]], align 8
70 ; CHECK-NEXT:    ret void
72 entry:
73   br i1 %cond, label %bb1, label %bb3
75 bb3:
76   br label %bb2
78 bb1:
79   br label %bb2
81 bb2:
82   %ptr.2 = phi ptr [ %ptr, %bb3 ], [ null, %bb1 ]
83   store i8 2, ptr %ptr.2, align 8
84   ret void
87 declare void @llvm.assume(i1)
88 declare i1 @llvm.type.test(ptr, metadata) nounwind readnone
90 ;; Same as the above test but make sure the unreachable control flow is still
91 ;; removed in the presence of a type test / assume sequence.
93 define void @test5_type_test_assume(i1 %cond, ptr %ptr, ptr %vtable) {
94 ; CHECK-LABEL: @test5_type_test_assume(
95 ; CHECK-NEXT:  entry:
96 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[COND:%.*]], true
97 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
98 ; CHECK-NEXT:    [[P:%.*]] = call i1 @llvm.type.test(ptr [[VTABLE:%.*]], metadata !"foo")
99 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[P]])
100 ; CHECK-NEXT:    store i8 2, ptr [[PTR:%.*]], align 8
101 ; CHECK-NEXT:    ret void
103 entry:
104   br i1 %cond, label %bb1, label %bb3
106 bb3:
107   br label %bb2
109 bb1:
110   br label %bb2
112 bb2:
113   %ptr.2 = phi ptr [ %ptr, %bb3 ], [ null, %bb1 ]
114   %p = call i1 @llvm.type.test(ptr %vtable, metadata !"foo")
115   tail call void @llvm.assume(i1 %p)
116   store i8 2, ptr %ptr.2, align 8
117   ret void
120 define void @test5_no_null_opt(i1 %cond, ptr %ptr) #0 {
121 ; CHECK-LABEL: @test5_no_null_opt(
122 ; CHECK-NEXT:  entry:
123 ; CHECK-NEXT:    [[DOTPTR:%.*]] = select i1 [[COND:%.*]], ptr null, ptr [[PTR:%.*]]
124 ; CHECK-NEXT:    store i8 2, ptr [[DOTPTR]], align 8
125 ; CHECK-NEXT:    ret void
127 entry:
128   br i1 %cond, label %bb1, label %bb3
130 bb3:
131   br label %bb2
133 bb1:
134   br label %bb2
136 bb2:
137   %ptr.2 = phi ptr [ %ptr, %bb3 ], [ null, %bb1 ]
138   store i8 2, ptr %ptr.2, align 8
139   ret void
142 define void @test6(i1 %cond, ptr %ptr) {
143 ; CHECK-LABEL: @test6(
144 ; CHECK-NEXT:  entry:
145 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[COND:%.*]], true
146 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
147 ; CHECK-NEXT:    store i8 2, ptr [[PTR:%.*]], align 8
148 ; CHECK-NEXT:    ret void
150 entry:
151   br i1 %cond, label %bb1, label %bb2
153 bb1:
154   br label %bb2
156 bb2:
157   %ptr.2 = phi ptr [ %ptr, %entry ], [ null, %bb1 ]
158   store i8 2, ptr %ptr.2, align 8
159   ret void
162 define void @test6_no_null_opt(i1 %cond, ptr %ptr) #0 {
163 ; CHECK-LABEL: @test6_no_null_opt(
164 ; CHECK-NEXT:  entry:
165 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[COND:%.*]], ptr null, ptr [[PTR:%.*]]
166 ; CHECK-NEXT:    store i8 2, ptr [[SPEC_SELECT]], align 8
167 ; CHECK-NEXT:    ret void
169 entry:
170   br i1 %cond, label %bb1, label %bb2
172 bb1:
173   br label %bb2
175 bb2:
176   %ptr.2 = phi ptr [ %ptr, %entry ], [ null, %bb1 ]
177   store i8 2, ptr %ptr.2, align 8
178   ret void
182 define i32 @test7(i1 %X) {
183 ; CHECK-LABEL: @test7(
184 ; CHECK-NEXT:  entry:
185 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
186 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
187 ; CHECK-NEXT:    ret i32 0
189 entry:
190   br i1 %X, label %if, label %else
193   call void undef()
194   br label %else
196 else:
197   %phi = phi i32 [ 0, %entry ], [ 1, %if ]
198   ret i32 %phi
201 define void @test8(i1 %X, ptr %Y) {
202 ; CHECK-LABEL: @test8(
203 ; CHECK-NEXT:  entry:
204 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
205 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
206 ; CHECK-NEXT:    call void [[Y:%.*]]()
207 ; CHECK-NEXT:    ret void
209 entry:
210   br i1 %X, label %if, label %else
213   br label %else
215 else:
216   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
217   call void %phi()
218   ret void
221 define void @test8_no_null_opt(i1 %X, ptr %Y) #0 {
222 ; CHECK-LABEL: @test8_no_null_opt(
223 ; CHECK-NEXT:  entry:
224 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
225 ; CHECK-NEXT:    call void [[SPEC_SELECT]]()
226 ; CHECK-NEXT:    ret void
228 entry:
229   br i1 %X, label %if, label %else
232   br label %else
234 else:
235   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
236   call void %phi()
237   ret void
240 declare ptr @fn_nonnull_noundef_arg(ptr nonnull noundef %p)
241 declare ptr @fn_nonnull_deref_arg(ptr nonnull dereferenceable(4) %p)
242 declare ptr @fn_nonnull_deref_or_null_arg(ptr nonnull dereferenceable_or_null(4) %p)
243 declare ptr @fn_nonnull_arg(ptr nonnull %p)
244 declare ptr @fn_noundef_arg(ptr noundef %p)
246 define void @test9(i1 %X, ptr %Y) {
247 ; CHECK-LABEL: @test9(
248 ; CHECK-NEXT:  entry:
249 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
250 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
251 ; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[Y:%.*]])
252 ; CHECK-NEXT:    ret void
254 entry:
255   br i1 %X, label %if, label %else
258   br label %else
260 else:
261   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
262   call ptr @fn_nonnull_noundef_arg(ptr %phi)
263   ret void
266 ; Optimizing this code should produce assume.
267 define void @test9_deref(i1 %X, ptr %Y) {
268 ; CHECK-LABEL: @test9_deref(
269 ; CHECK-NEXT:  entry:
270 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
271 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
272 ; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_deref_arg(ptr [[Y:%.*]])
273 ; CHECK-NEXT:    ret void
275 entry:
276   br i1 %X, label %if, label %else
279   br label %else
281 else:
282   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
283   call ptr @fn_nonnull_deref_arg(ptr %phi)
284   ret void
287 ; Optimizing this code should produce assume.
288 define void @test9_deref_or_null(i1 %X, ptr %Y) {
289 ; CHECK-LABEL: @test9_deref_or_null(
290 ; CHECK-NEXT:  entry:
291 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
292 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
293 ; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_deref_or_null_arg(ptr [[Y:%.*]])
294 ; CHECK-NEXT:    ret void
296 entry:
297   br i1 %X, label %if, label %else
300   br label %else
302 else:
303   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
304   call ptr @fn_nonnull_deref_or_null_arg(ptr %phi)
305   ret void
308 define void @test9_undef(i1 %X, ptr %Y) {
309 ; CHECK-LABEL: @test9_undef(
310 ; CHECK-NEXT:  entry:
311 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[Y:%.*]])
312 ; CHECK-NEXT:    ret void
314 entry:
315   br i1 %X, label %if, label %else
318   br label %else
320 else:
321   %phi = phi ptr [ %Y, %entry ], [ undef, %if ]
322   call ptr @fn_noundef_arg(ptr %phi)
323   ret void
326 define void @test9_undef_null_defined(i1 %X, ptr %Y) #0 {
327 ; CHECK-LABEL: @test9_undef_null_defined(
328 ; CHECK-NEXT:  entry:
329 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[Y:%.*]])
330 ; CHECK-NEXT:    ret void
332 entry:
333   br i1 %X, label %if, label %else
336   br label %else
338 else:
339   %phi = phi ptr [ %Y, %entry ], [ undef, %if ]
340   call ptr @fn_noundef_arg(ptr %phi)
341   ret void
344 define void @test9_null_callsite(i1 %X, ptr %Y) {
345 ; CHECK-LABEL: @test9_null_callsite(
346 ; CHECK-NEXT:  entry:
347 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
348 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
349 ; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_arg(ptr noundef nonnull [[Y:%.*]])
350 ; CHECK-NEXT:    ret void
352 entry:
353   br i1 %X, label %if, label %else
356   br label %else
358 else:
359   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
360   call ptr @fn_nonnull_arg(ptr nonnull noundef %phi)
361   ret void
364 define void @test9_gep_mismatch(i1 %X, ptr %Y,  ptr %P) {
365 ; CHECK-LABEL: @test9_gep_mismatch(
366 ; CHECK-NEXT:  entry:
367 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
368 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[P:%.*]])
369 ; CHECK-NEXT:    ret void
371 entry:
372   br i1 %X, label %if, label %else
375   br label %else
377 else:
378   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
379   call ptr @fn_nonnull_noundef_arg(ptr %P)
380   ret void
383 define void @test9_gep_zero(i1 %X, ptr %Y) {
384 ; CHECK-LABEL: @test9_gep_zero(
385 ; CHECK-NEXT:  entry:
386 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
387 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
388 ; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[Y:%.*]])
389 ; CHECK-NEXT:    ret void
391 entry:
392   br i1 %X, label %if, label %else
395   br label %else
397 else:
398   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
399   call ptr @fn_nonnull_noundef_arg(ptr %phi)
400   ret void
403 define void @test9_gep_bitcast(i1 %X, ptr %Y) {
404 ; CHECK-LABEL: @test9_gep_bitcast(
405 ; CHECK-NEXT:  entry:
406 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
407 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
408 ; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[Y:%.*]])
409 ; CHECK-NEXT:    ret void
411 entry:
412   br i1 %X, label %if, label %else
415   br label %else
417 else:
418   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
419   call ptr @fn_nonnull_noundef_arg(ptr %phi)
420   ret void
423 define void @test9_gep_nonzero(i1 %X, ptr %Y) {
424 ; CHECK-LABEL: @test9_gep_nonzero(
425 ; CHECK-NEXT:  entry:
426 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
427 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[SPEC_SELECT]], i64 12
428 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
429 ; CHECK-NEXT:    ret void
431 entry:
432   br i1 %X, label %if, label %else
435   br label %else
437 else:
438   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
439   %gep = getelementptr i8, ptr %phi, i64 12
440   call ptr @fn_nonnull_noundef_arg(ptr %gep)
441   ret void
444 define void @test9_gep_inbounds_nonzero(i1 %X, ptr %Y) {
445 ; CHECK-LABEL: @test9_gep_inbounds_nonzero(
446 ; CHECK-NEXT:  entry:
447 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
448 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[SPEC_SELECT]], i64 12
449 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
450 ; CHECK-NEXT:    ret void
452 entry:
453   br i1 %X, label %if, label %else
456   br label %else
458 else:
459   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
460   %gep = getelementptr inbounds i8, ptr %phi, i64 12
461   call ptr @fn_nonnull_noundef_arg(ptr %gep)
462   ret void
466 define void @test9_gep_inbouds_unknown_null(i1 %X, ptr %Y, i64 %I) {
467 ; CHECK-LABEL: @test9_gep_inbouds_unknown_null(
468 ; CHECK-NEXT:  entry:
469 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
470 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[SPEC_SELECT]], i64 [[I:%.*]]
471 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
472 ; CHECK-NEXT:    ret void
474 entry:
475   br i1 %X, label %if, label %else
478   br label %else
480 else:
481   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
482   %gep = getelementptr inbounds i8, ptr %phi, i64 %I
483   call ptr @fn_nonnull_noundef_arg(ptr %gep)
484   ret void
487 define void @test9_gep_unknown_null(i1 %X, ptr %Y, i64 %I) {
488 ; CHECK-LABEL: @test9_gep_unknown_null(
489 ; CHECK-NEXT:  entry:
490 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
491 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[SPEC_SELECT]], i64 [[I:%.*]]
492 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
493 ; CHECK-NEXT:    ret void
495 entry:
496   br i1 %X, label %if, label %else
499   br label %else
501 else:
502   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
503   %gep = getelementptr i8, ptr %phi, i64 %I
504   call ptr @fn_nonnull_noundef_arg(ptr %gep)
505   ret void
508 define void @test9_gep_unknown_undef(i1 %X, ptr %Y, i64 %I) {
509 ; CHECK-LABEL: @test9_gep_unknown_undef(
510 ; CHECK-NEXT:  entry:
511 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[Y:%.*]], i64 [[I:%.*]]
512 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[GEP]])
513 ; CHECK-NEXT:    ret void
515 entry:
516   br i1 %X, label %if, label %else
519   br label %else
521 else:
522   %phi = phi ptr [ %Y, %entry ], [ undef, %if ]
523   %gep = getelementptr i8, ptr %phi, i64 %I
524   call ptr @fn_noundef_arg(ptr %gep)
525   ret void
528 define void @test9_missing_noundef(i1 %X, ptr %Y) {
529 ; CHECK-LABEL: @test9_missing_noundef(
530 ; CHECK-NEXT:  entry:
531 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
532 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_arg(ptr [[SPEC_SELECT]])
533 ; CHECK-NEXT:    ret void
535 entry:
536   br i1 %X, label %if, label %else
539   br label %else
541 else:
542   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
543   call ptr @fn_nonnull_arg(ptr %phi)
544   ret void
547 define void @test9_null_defined(i1 %X, ptr %Y) #0 {
548 ; CHECK-LABEL: @test9_null_defined(
549 ; CHECK-NEXT:  entry:
550 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
551 ; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[SPEC_SELECT]])
552 ; CHECK-NEXT:    ret void
554 entry:
555   br i1 %X, label %if, label %else
558   br label %else
560 else:
561   %phi = phi ptr [ %Y, %entry ], [ null, %if ]
562   call ptr @fn_nonnull_noundef_arg(ptr %phi)
563   ret void
568 attributes #0 = { null_pointer_is_valid }
570 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
571 ; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
572 ; CHECK: attributes #[[ATTR2:[0-9]+]] = { null_pointer_is_valid }
573 ; CHECK: attributes #[[ATTR3]] = { nounwind }