[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / UnreachableEliminate.ll
blob0d6b941bb84f677a51d7b01508b7cbe43b90df25
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1  -S | FileCheck %s
4 define void @test1(i1 %C, i1* %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, i1* %BP
15   unreachable
17   ret void
20 define void @test2() personality i32 (...)* @__gxx_personality_v0 {
21 ; CHECK-LABEL: @test2(
22 ; CHECK-NEXT:  entry:
23 ; CHECK-NEXT:    call void @test2()
24 ; CHECK-NEXT:    ret void
26 entry:
27   invoke void @test2( )
28   to label %N unwind label %U
30   %res = landingpad { i8* }
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, i8* %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, i8* [[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 i8* [ %ptr, %bb3 ], [ null, %bb1 ]
83   store i8 2, i8* %ptr.2, align 8
84   ret void
87 declare void @llvm.assume(i1)
88 declare i1 @llvm.type.test(i8*, 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, i8* %ptr, [3 x i8*]* %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:    [[VTABLE:%.*]] = bitcast [3 x i8*]* %vtable to i8*
99 ; CHECK-NEXT:    [[P:%.*]] = call i1 @llvm.type.test(i8* [[VTABLE]], metadata !"foo")
100 ; CHECK-NEXT:    tail call void @llvm.assume(i1 [[P]])
101 ; CHECK-NEXT:    store i8 2, i8* [[PTR:%.*]], align 8
102 ; CHECK-NEXT:    ret void
104 entry:
105   br i1 %cond, label %bb1, label %bb3
107 bb3:
108   br label %bb2
110 bb1:
111   br label %bb2
113 bb2:
114   %ptr.2 = phi i8* [ %ptr, %bb3 ], [ null, %bb1 ]
115   %vtablei8 = bitcast [3 x i8*]* %vtable to i8*
116   %p = call i1 @llvm.type.test(i8* %vtablei8, metadata !"foo")
117   tail call void @llvm.assume(i1 %p)
118   store i8 2, i8* %ptr.2, align 8
119   ret void
122 define void @test5_no_null_opt(i1 %cond, i8* %ptr) #0 {
123 ; CHECK-LABEL: @test5_no_null_opt(
124 ; CHECK-NEXT:  entry:
125 ; CHECK-NEXT:    [[PTR_2:%.*]] = select i1 [[COND:%.*]], i8* null, i8* [[PTR:%.*]]
126 ; CHECK-NEXT:    store i8 2, i8* [[PTR_2]], align 8
127 ; CHECK-NEXT:    ret void
129 entry:
130   br i1 %cond, label %bb1, label %bb3
132 bb3:
133   br label %bb2
135 bb1:
136   br label %bb2
138 bb2:
139   %ptr.2 = phi i8* [ %ptr, %bb3 ], [ null, %bb1 ]
140   store i8 2, i8* %ptr.2, align 8
141   ret void
144 define void @test6(i1 %cond, i8* %ptr) {
145 ; CHECK-LABEL: @test6(
146 ; CHECK-NEXT:  entry:
147 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[COND:%.*]], true
148 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
149 ; CHECK-NEXT:    store i8 2, i8* [[PTR:%.*]], align 8
150 ; CHECK-NEXT:    ret void
152 entry:
153   br i1 %cond, label %bb1, label %bb2
155 bb1:
156   br label %bb2
158 bb2:
159   %ptr.2 = phi i8* [ %ptr, %entry ], [ null, %bb1 ]
160   store i8 2, i8* %ptr.2, align 8
161   ret void
164 define void @test6_no_null_opt(i1 %cond, i8* %ptr) #0 {
165 ; CHECK-LABEL: @test6_no_null_opt(
166 ; CHECK-NEXT:  entry:
167 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[COND:%.*]], i8* null, i8* [[PTR:%.*]]
168 ; CHECK-NEXT:    store i8 2, i8* [[SPEC_SELECT]], align 8
169 ; CHECK-NEXT:    ret void
171 entry:
172   br i1 %cond, label %bb1, label %bb2
174 bb1:
175   br label %bb2
177 bb2:
178   %ptr.2 = phi i8* [ %ptr, %entry ], [ null, %bb1 ]
179   store i8 2, i8* %ptr.2, align 8
180   ret void
184 define i32 @test7(i1 %X) {
185 ; CHECK-LABEL: @test7(
186 ; CHECK-NEXT:  entry:
187 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
188 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
189 ; CHECK-NEXT:    ret i32 0
191 entry:
192   br i1 %X, label %if, label %else
195   call void undef()
196   br label %else
198 else:
199   %phi = phi i32 [ 0, %entry ], [ 1, %if ]
200   ret i32 %phi
203 define void @test8(i1 %X, void ()* %Y) {
204 ; CHECK-LABEL: @test8(
205 ; CHECK-NEXT:  entry:
206 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
207 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
208 ; CHECK-NEXT:    call void [[Y:%.*]]()
209 ; CHECK-NEXT:    ret void
211 entry:
212   br i1 %X, label %if, label %else
215   br label %else
217 else:
218   %phi = phi void ()* [ %Y, %entry ], [ null, %if ]
219   call void %phi()
220   ret void
223 define void @test8_no_null_opt(i1 %X, void ()* %Y) #0 {
224 ; CHECK-LABEL: @test8_no_null_opt(
225 ; CHECK-NEXT:  entry:
226 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], void ()* null, void ()* [[Y:%.*]]
227 ; CHECK-NEXT:    call void [[SPEC_SELECT]]()
228 ; CHECK-NEXT:    ret void
230 entry:
231   br i1 %X, label %if, label %else
234   br label %else
236 else:
237   %phi = phi void ()* [ %Y, %entry ], [ null, %if ]
238   call void %phi()
239   ret void
242 declare i8* @fn_nonnull_noundef_arg(i8* nonnull noundef %p)
243 declare i8* @fn_nonnull_deref_arg(i8* nonnull dereferenceable(4) %p)
244 declare i8* @fn_nonnull_deref_or_null_arg(i8* nonnull dereferenceable_or_null(4) %p)
245 declare i8* @fn_nonnull_arg(i8* nonnull %p)
246 declare i8* @fn_noundef_arg(i8* noundef %p)
248 define void @test9(i1 %X, i8* %Y) {
249 ; CHECK-LABEL: @test9(
250 ; CHECK-NEXT:  entry:
251 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
252 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
253 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @fn_nonnull_noundef_arg(i8* [[Y:%.*]])
254 ; CHECK-NEXT:    ret void
256 entry:
257   br i1 %X, label %if, label %else
260   br label %else
262 else:
263   %phi = phi i8* [ %Y, %entry ], [ null, %if ]
264   call i8* @fn_nonnull_noundef_arg(i8* %phi)
265   ret void
268 ; Optimizing this code should produce assume.
269 define void @test9_deref(i1 %X, i8* %Y) {
270 ; CHECK-LABEL: @test9_deref(
271 ; CHECK-NEXT:  entry:
272 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
273 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
274 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @fn_nonnull_deref_arg(i8* [[Y:%.*]])
275 ; CHECK-NEXT:    ret void
277 entry:
278   br i1 %X, label %if, label %else
281   br label %else
283 else:
284   %phi = phi i8* [ %Y, %entry ], [ null, %if ]
285   call i8* @fn_nonnull_deref_arg(i8* %phi)
286   ret void
289 ; Optimizing this code should produce assume.
290 define void @test9_deref_or_null(i1 %X, i8* %Y) {
291 ; CHECK-LABEL: @test9_deref_or_null(
292 ; CHECK-NEXT:  entry:
293 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
294 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
295 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @fn_nonnull_deref_or_null_arg(i8* [[Y:%.*]])
296 ; CHECK-NEXT:    ret void
298 entry:
299   br i1 %X, label %if, label %else
302   br label %else
304 else:
305   %phi = phi i8* [ %Y, %entry ], [ null, %if ]
306   call i8* @fn_nonnull_deref_or_null_arg(i8* %phi)
307   ret void
310 define void @test9_undef(i1 %X, i8* %Y) {
311 ; CHECK-LABEL: @test9_undef(
312 ; CHECK-NEXT:  entry:
313 ; CHECK-NEXT:    [[TMP0:%.*]] = call i8* @fn_noundef_arg(i8* [[Y:%.*]])
314 ; CHECK-NEXT:    ret void
316 entry:
317   br i1 %X, label %if, label %else
320   br label %else
322 else:
323   %phi = phi i8* [ %Y, %entry ], [ undef, %if ]
324   call i8* @fn_noundef_arg(i8* %phi)
325   ret void
328 define void @test9_undef_null_defined(i1 %X, i8* %Y) #0 {
329 ; CHECK-LABEL: @test9_undef_null_defined(
330 ; CHECK-NEXT:  entry:
331 ; CHECK-NEXT:    [[TMP0:%.*]] = call i8* @fn_noundef_arg(i8* [[Y:%.*]])
332 ; CHECK-NEXT:    ret void
334 entry:
335   br i1 %X, label %if, label %else
338   br label %else
340 else:
341   %phi = phi i8* [ %Y, %entry ], [ undef, %if ]
342   call i8* @fn_noundef_arg(i8* %phi)
343   ret void
346 define void @test9_null_callsite(i1 %X, i8* %Y) {
347 ; CHECK-LABEL: @test9_null_callsite(
348 ; CHECK-NEXT:  entry:
349 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
350 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
351 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @fn_nonnull_arg(i8* noundef nonnull [[Y:%.*]])
352 ; CHECK-NEXT:    ret void
354 entry:
355   br i1 %X, label %if, label %else
358   br label %else
360 else:
361   %phi = phi i8* [ %Y, %entry ], [ null, %if ]
362   call i8* @fn_nonnull_arg(i8* nonnull noundef %phi)
363   ret void
366 define void @test9_gep_mismatch(i1 %X, i8* %Y,  i8* %P) {
367 ; CHECK-LABEL: @test9_gep_mismatch(
368 ; CHECK-NEXT:  entry:
369 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], i8* null, i8* [[Y:%.*]]
370 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, i8* [[P:%.*]], i64 0
371 ; CHECK-NEXT:    [[TMP0:%.*]] = call i8* @fn_nonnull_noundef_arg(i8* [[GEP]])
372 ; CHECK-NEXT:    ret void
374 entry:
375   br i1 %X, label %if, label %else
378   br label %else
380 else:
381   %phi = phi i8* [ %Y, %entry ], [ null, %if ]
382   %gep = getelementptr inbounds i8, i8* %P, i64 0
383   call i8* @fn_nonnull_noundef_arg(i8* %gep)
384   ret void
387 define void @test9_gep_zero(i1 %X, i8* %Y) {
388 ; CHECK-LABEL: @test9_gep_zero(
389 ; CHECK-NEXT:  entry:
390 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
391 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
392 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, i8* [[Y:%.*]], i64 0
393 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @fn_nonnull_noundef_arg(i8* [[GEP]])
394 ; CHECK-NEXT:    ret void
396 entry:
397   br i1 %X, label %if, label %else
400   br label %else
402 else:
403   %phi = phi i8* [ %Y, %entry ], [ null, %if ]
404   %gep = getelementptr inbounds i8, i8* %phi, i64 0
405   call i8* @fn_nonnull_noundef_arg(i8* %gep)
406   ret void
409 define void @test9_gep_bitcast(i1 %X, i32* %Y) {
410 ; CHECK-LABEL: @test9_gep_bitcast(
411 ; CHECK-NEXT:  entry:
412 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
413 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
414 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i32, i32* [[Y:%.*]], i64 0
415 ; CHECK-NEXT:    [[BC:%.*]] = bitcast i32* [[GEP]] to i8*
416 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8* @fn_nonnull_noundef_arg(i8* [[BC]])
417 ; CHECK-NEXT:    ret void
419 entry:
420   br i1 %X, label %if, label %else
423   br label %else
425 else:
426   %phi = phi i32* [ %Y, %entry ], [ null, %if ]
427   %gep = getelementptr inbounds i32, i32* %phi, i64 0
428   %bc = bitcast i32* %gep to i8*
429   call i8* @fn_nonnull_noundef_arg(i8* %bc)
430   ret void
433 define void @test9_gep_nonzero(i1 %X, i8* %Y) {
434 ; CHECK-LABEL: @test9_gep_nonzero(
435 ; CHECK-NEXT:  entry:
436 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], i8* null, i8* [[Y:%.*]]
437 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, i8* [[SPEC_SELECT]], i64 12
438 ; CHECK-NEXT:    [[TMP0:%.*]] = call i8* @fn_nonnull_noundef_arg(i8* [[GEP]])
439 ; CHECK-NEXT:    ret void
441 entry:
442   br i1 %X, label %if, label %else
445   br label %else
447 else:
448   %phi = phi i8* [ %Y, %entry ], [ null, %if ]
449   %gep = getelementptr i8, i8* %phi, i64 12
450   call i8* @fn_nonnull_noundef_arg(i8* %gep)
451   ret void
454 define void @test9_gep_inbounds_nonzero(i1 %X, i8* %Y) {
455 ; CHECK-LABEL: @test9_gep_inbounds_nonzero(
456 ; CHECK-NEXT:  entry:
457 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], i8* null, i8* [[Y:%.*]]
458 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, i8* [[SPEC_SELECT]], i64 12
459 ; CHECK-NEXT:    [[TMP0:%.*]] = call i8* @fn_nonnull_noundef_arg(i8* [[GEP]])
460 ; CHECK-NEXT:    ret void
462 entry:
463   br i1 %X, label %if, label %else
466   br label %else
468 else:
469   %phi = phi i8* [ %Y, %entry ], [ null, %if ]
470   %gep = getelementptr inbounds i8, i8* %phi, i64 12
471   call i8* @fn_nonnull_noundef_arg(i8* %gep)
472   ret void
476 define void @test9_gep_inbouds_unknown_null(i1 %X, i8* %Y, i64 %I) {
477 ; CHECK-LABEL: @test9_gep_inbouds_unknown_null(
478 ; CHECK-NEXT:  entry:
479 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], i8* null, i8* [[Y:%.*]]
480 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, i8* [[SPEC_SELECT]], i64 [[I:%.*]]
481 ; CHECK-NEXT:    [[TMP0:%.*]] = call i8* @fn_nonnull_noundef_arg(i8* [[GEP]])
482 ; CHECK-NEXT:    ret void
484 entry:
485   br i1 %X, label %if, label %else
488   br label %else
490 else:
491   %phi = phi i8* [ %Y, %entry ], [ null, %if ]
492   %gep = getelementptr inbounds i8, i8* %phi, i64 %I
493   call i8* @fn_nonnull_noundef_arg(i8* %gep)
494   ret void
497 define void @test9_gep_unknown_null(i1 %X, i8* %Y, i64 %I) {
498 ; CHECK-LABEL: @test9_gep_unknown_null(
499 ; CHECK-NEXT:  entry:
500 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], i8* null, i8* [[Y:%.*]]
501 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, i8* [[SPEC_SELECT]], i64 [[I:%.*]]
502 ; CHECK-NEXT:    [[TMP0:%.*]] = call i8* @fn_nonnull_noundef_arg(i8* [[GEP]])
503 ; CHECK-NEXT:    ret void
505 entry:
506   br i1 %X, label %if, label %else
509   br label %else
511 else:
512   %phi = phi i8* [ %Y, %entry ], [ null, %if ]
513   %gep = getelementptr i8, i8* %phi, i64 %I
514   call i8* @fn_nonnull_noundef_arg(i8* %gep)
515   ret void
518 define void @test9_gep_unknown_undef(i1 %X, i8* %Y, i64 %I) {
519 ; CHECK-LABEL: @test9_gep_unknown_undef(
520 ; CHECK-NEXT:  entry:
521 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, i8* [[Y:%.*]], i64 [[I:%.*]]
522 ; CHECK-NEXT:    [[TMP0:%.*]] = call i8* @fn_noundef_arg(i8* [[GEP]])
523 ; CHECK-NEXT:    ret void
525 entry:
526   br i1 %X, label %if, label %else
529   br label %else
531 else:
532   %phi = phi i8* [ %Y, %entry ], [ undef, %if ]
533   %gep = getelementptr i8, i8* %phi, i64 %I
534   call i8* @fn_noundef_arg(i8* %gep)
535   ret void
538 define void @test9_missing_noundef(i1 %X, i8* %Y) {
539 ; CHECK-LABEL: @test9_missing_noundef(
540 ; CHECK-NEXT:  entry:
541 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], i8* null, i8* [[Y:%.*]]
542 ; CHECK-NEXT:    [[TMP0:%.*]] = call i8* @fn_nonnull_arg(i8* [[SPEC_SELECT]])
543 ; CHECK-NEXT:    ret void
545 entry:
546   br i1 %X, label %if, label %else
549   br label %else
551 else:
552   %phi = phi i8* [ %Y, %entry ], [ null, %if ]
553   call i8* @fn_nonnull_arg(i8* %phi)
554   ret void
557 define void @test9_null_defined(i1 %X, i8* %Y) #0 {
558 ; CHECK-LABEL: @test9_null_defined(
559 ; CHECK-NEXT:  entry:
560 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], i8* null, i8* [[Y:%.*]]
561 ; CHECK-NEXT:    [[TMP0:%.*]] = call i8* @fn_nonnull_noundef_arg(i8* [[SPEC_SELECT]])
562 ; CHECK-NEXT:    ret void
564 entry:
565   br i1 %X, label %if, label %else
568   br label %else
570 else:
571   %phi = phi i8* [ %Y, %entry ], [ null, %if ]
572   call i8* @fn_nonnull_noundef_arg(i8* %phi)
573   ret void
578 attributes #0 = { null_pointer_is_valid }