xref: /llvm-project/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll (revision 37932643abab699e8bb1def08b7eb4eae7ff1448)
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
3
4define 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
10;
11entry:
12  br i1 %C, label %T, label %F
13T:
14  store i1 %C, ptr %BP
15  unreachable
16F:
17  ret void
18}
19
20define void @test2() personality ptr @__gxx_personality_v0 {
21; CHECK-LABEL: @test2(
22; CHECK-NEXT:  entry:
23; CHECK-NEXT:    call void @test2() #[[ATTR4:[0-9]+]]
24; CHECK-NEXT:    ret void
25;
26entry:
27  invoke void @test2( )
28  to label %N unwind label %U
29U:
30  %res = landingpad { ptr }
31  cleanup
32  unreachable
33N:
34  ret void
35}
36
37declare i32 @__gxx_personality_v0(...)
38
39define 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]]
45;
46entry:
47  switch i32 %v, label %default [
48  i32 1, label %U
49  i32 2, label %T
50  ]
51default:
52  ret i32 1
53U:
54  unreachable
55T:
56  ret i32 2
57}
58
59
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.
63
64define 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
71;
72entry:
73  br i1 %cond, label %bb1, label %bb3
74
75bb3:
76  br label %bb2
77
78bb1:
79  br label %bb2
80
81bb2:
82  %ptr.2 = phi ptr [ %ptr, %bb3 ], [ null, %bb1 ]
83  store i8 2, ptr %ptr.2, align 8
84  ret void
85}
86
87declare void @llvm.assume(i1)
88declare i1 @llvm.type.test(ptr, metadata) nounwind readnone
89
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.
92
93define 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
102;
103entry:
104  br i1 %cond, label %bb1, label %bb3
105
106bb3:
107  br label %bb2
108
109bb1:
110  br label %bb2
111
112bb2:
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
118}
119
120define 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
126;
127entry:
128  br i1 %cond, label %bb1, label %bb3
129
130bb3:
131  br label %bb2
132
133bb1:
134  br label %bb2
135
136bb2:
137  %ptr.2 = phi ptr [ %ptr, %bb3 ], [ null, %bb1 ]
138  store i8 2, ptr %ptr.2, align 8
139  ret void
140}
141
142define 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
149;
150entry:
151  br i1 %cond, label %bb1, label %bb2
152
153bb1:
154  br label %bb2
155
156bb2:
157  %ptr.2 = phi ptr [ %ptr, %entry ], [ null, %bb1 ]
158  store i8 2, ptr %ptr.2, align 8
159  ret void
160}
161
162define 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
168;
169entry:
170  br i1 %cond, label %bb1, label %bb2
171
172bb1:
173  br label %bb2
174
175bb2:
176  %ptr.2 = phi ptr [ %ptr, %entry ], [ null, %bb1 ]
177  store i8 2, ptr %ptr.2, align 8
178  ret void
179}
180
181
182define 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
188;
189entry:
190  br i1 %X, label %if, label %else
191
192if:
193  call void undef()
194  br label %else
195
196else:
197  %phi = phi i32 [ 0, %entry ], [ 1, %if ]
198  ret i32 %phi
199}
200
201define 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
208;
209entry:
210  br i1 %X, label %if, label %else
211
212if:
213  br label %else
214
215else:
216  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
217  call void %phi()
218  ret void
219}
220
221define 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
227;
228entry:
229  br i1 %X, label %if, label %else
230
231if:
232  br label %else
233
234else:
235  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
236  call void %phi()
237  ret void
238}
239
240declare ptr @fn_nonnull_noundef_arg(ptr nonnull noundef %p)
241declare ptr @fn_nonnull_deref_arg(ptr nonnull dereferenceable(4) %p)
242declare ptr @fn_nonnull_deref_or_null_arg(ptr nonnull dereferenceable_or_null(4) %p)
243declare ptr @fn_nonnull_arg(ptr nonnull %p)
244declare ptr @fn_noundef_arg(ptr noundef %p)
245declare ptr @fn_ptr_arg(ptr)
246declare ptr @fn_ptr_arg_nounwind_willreturn(ptr) nounwind willreturn
247
248define void @test9(i1 %X, ptr %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 ptr @fn_nonnull_noundef_arg(ptr [[Y:%.*]])
254; CHECK-NEXT:    ret void
255;
256entry:
257  br i1 %X, label %if, label %else
258
259if:
260  br label %else
261
262else:
263  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
264  call ptr @fn_nonnull_noundef_arg(ptr %phi)
265  ret void
266}
267
268; Optimizing this code should produce assume.
269define void @test9_deref(i1 %X, ptr %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 ptr @fn_nonnull_deref_arg(ptr [[Y:%.*]])
275; CHECK-NEXT:    ret void
276;
277entry:
278  br i1 %X, label %if, label %else
279
280if:
281  br label %else
282
283else:
284  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
285  call ptr @fn_nonnull_deref_arg(ptr %phi)
286  ret void
287}
288
289; Optimizing this code should produce assume.
290define void @test9_deref_or_null(i1 %X, ptr %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 ptr @fn_nonnull_deref_or_null_arg(ptr [[Y:%.*]])
296; CHECK-NEXT:    ret void
297;
298entry:
299  br i1 %X, label %if, label %else
300
301if:
302  br label %else
303
304else:
305  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
306  call ptr @fn_nonnull_deref_or_null_arg(ptr %phi)
307  ret void
308}
309
310define void @test9_undef(i1 %X, ptr %Y) {
311; CHECK-LABEL: @test9_undef(
312; CHECK-NEXT:  entry:
313; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[Y:%.*]])
314; CHECK-NEXT:    ret void
315;
316entry:
317  br i1 %X, label %if, label %else
318
319if:
320  br label %else
321
322else:
323  %phi = phi ptr [ %Y, %entry ], [ undef, %if ]
324  call ptr @fn_noundef_arg(ptr %phi)
325  ret void
326}
327
328define void @test9_undef_null_defined(i1 %X, ptr %Y) #0 {
329; CHECK-LABEL: @test9_undef_null_defined(
330; CHECK-NEXT:  entry:
331; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[Y:%.*]])
332; CHECK-NEXT:    ret void
333;
334entry:
335  br i1 %X, label %if, label %else
336
337if:
338  br label %else
339
340else:
341  %phi = phi ptr [ %Y, %entry ], [ undef, %if ]
342  call ptr @fn_noundef_arg(ptr %phi)
343  ret void
344}
345
346define void @test9_null_callsite(i1 %X, ptr %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 ptr @fn_nonnull_arg(ptr noundef nonnull [[Y:%.*]])
352; CHECK-NEXT:    ret void
353;
354entry:
355  br i1 %X, label %if, label %else
356
357if:
358  br label %else
359
360else:
361  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
362  call ptr @fn_nonnull_arg(ptr nonnull noundef %phi)
363  ret void
364}
365
366define void @test9_gep_mismatch(i1 %X, ptr %Y,  ptr %P) {
367; CHECK-LABEL: @test9_gep_mismatch(
368; CHECK-NEXT:  entry:
369; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
370; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[P:%.*]])
371; CHECK-NEXT:    ret void
372;
373entry:
374  br i1 %X, label %if, label %else
375
376if:
377  br label %else
378
379else:
380  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
381  call ptr @fn_nonnull_noundef_arg(ptr %P)
382  ret void
383}
384
385define void @test9_gep_zero(i1 %X, ptr %Y) {
386; CHECK-LABEL: @test9_gep_zero(
387; CHECK-NEXT:  entry:
388; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
389; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
390; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[Y:%.*]])
391; CHECK-NEXT:    ret void
392;
393entry:
394  br i1 %X, label %if, label %else
395
396if:
397  br label %else
398
399else:
400  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
401  call ptr @fn_nonnull_noundef_arg(ptr %phi)
402  ret void
403}
404
405define void @test9_gep_bitcast(i1 %X, ptr %Y) {
406; CHECK-LABEL: @test9_gep_bitcast(
407; CHECK-NEXT:  entry:
408; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
409; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
410; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[Y:%.*]])
411; CHECK-NEXT:    ret void
412;
413entry:
414  br i1 %X, label %if, label %else
415
416if:
417  br label %else
418
419else:
420  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
421  call ptr @fn_nonnull_noundef_arg(ptr %phi)
422  ret void
423}
424
425define void @test9_gep_nonzero(i1 %X, ptr %Y) {
426; CHECK-LABEL: @test9_gep_nonzero(
427; CHECK-NEXT:  entry:
428; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
429; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[SPEC_SELECT]], i64 12
430; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
431; CHECK-NEXT:    ret void
432;
433entry:
434  br i1 %X, label %if, label %else
435
436if:
437  br label %else
438
439else:
440  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
441  %gep = getelementptr i8, ptr %phi, i64 12
442  call ptr @fn_nonnull_noundef_arg(ptr %gep)
443  ret void
444}
445
446define void @test9_gep_inbounds_nonzero(i1 %X, ptr %Y) {
447; CHECK-LABEL: @test9_gep_inbounds_nonzero(
448; CHECK-NEXT:  entry:
449; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
450; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
451; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[Y:%.*]], i64 12
452; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
453; CHECK-NEXT:    ret void
454;
455entry:
456  br i1 %X, label %if, label %else
457
458if:
459  br label %else
460
461else:
462  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
463  %gep = getelementptr inbounds i8, ptr %phi, i64 12
464  call ptr @fn_nonnull_noundef_arg(ptr %gep)
465  ret void
466}
467
468define void @test9_gep_inbounds_nonzero_null_defined(i1 %X, ptr %Y) #0 {
469; CHECK-LABEL: @test9_gep_inbounds_nonzero_null_defined(
470; CHECK-NEXT:  entry:
471; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
472; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[SPEC_SELECT]], i64 12
473; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
474; CHECK-NEXT:    ret void
475;
476entry:
477  br i1 %X, label %if, label %else
478
479if:
480  br label %else
481
482else:
483  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
484  %gep = getelementptr inbounds i8, ptr %phi, i64 12
485  call ptr @fn_nonnull_noundef_arg(ptr %gep)
486  ret void
487}
488
489define void @test9_gep_inbounds_unknown_null(i1 %X, ptr %Y, i64 %I) {
490; CHECK-LABEL: @test9_gep_inbounds_unknown_null(
491; CHECK-NEXT:  entry:
492; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X:%.*]], true
493; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
494; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[Y:%.*]], i64 [[I:%.*]]
495; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
496; CHECK-NEXT:    ret void
497;
498entry:
499  br i1 %X, label %if, label %else
500
501if:
502  br label %else
503
504else:
505  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
506  %gep = getelementptr inbounds i8, ptr %phi, i64 %I
507  call ptr @fn_nonnull_noundef_arg(ptr %gep)
508  ret void
509}
510
511define void @test9_gep_inbounds_unknown_null_defined(i1 %X, ptr %Y, i64 %I) #0 {
512; CHECK-LABEL: @test9_gep_inbounds_unknown_null_defined(
513; CHECK-NEXT:  entry:
514; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
515; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[SPEC_SELECT]], i64 [[I:%.*]]
516; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
517; CHECK-NEXT:    ret void
518;
519entry:
520  br i1 %X, label %if, label %else
521
522if:
523  br label %else
524
525else:
526  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
527  %gep = getelementptr inbounds i8, ptr %phi, i64 %I
528  call ptr @fn_nonnull_noundef_arg(ptr %gep)
529  ret void
530}
531
532define void @test9_gep_inbounds_unknown_null_call_noundef(i1 %X, ptr %Y, i64 %I) {
533; CHECK-LABEL: @test9_gep_inbounds_unknown_null_call_noundef(
534; CHECK-NEXT:  entry:
535; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
536; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[SPEC_SELECT]], i64 [[I:%.*]]
537; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[GEP]])
538; CHECK-NEXT:    ret void
539;
540entry:
541  br i1 %X, label %if, label %else
542
543if:
544  br label %else
545
546else:
547  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
548  %gep = getelementptr inbounds i8, ptr %phi, i64 %I
549  call ptr @fn_noundef_arg(ptr %gep)
550  ret void
551}
552
553define void @test9_gep_unknown_null(i1 %X, ptr %Y, i64 %I) {
554; CHECK-LABEL: @test9_gep_unknown_null(
555; CHECK-NEXT:  entry:
556; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
557; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[SPEC_SELECT]], i64 [[I:%.*]]
558; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[GEP]])
559; CHECK-NEXT:    ret void
560;
561entry:
562  br i1 %X, label %if, label %else
563
564if:
565  br label %else
566
567else:
568  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
569  %gep = getelementptr i8, ptr %phi, i64 %I
570  call ptr @fn_nonnull_noundef_arg(ptr %gep)
571  ret void
572}
573
574define void @test9_gep_unknown_undef(i1 %X, ptr %Y, i64 %I) {
575; CHECK-LABEL: @test9_gep_unknown_undef(
576; CHECK-NEXT:  entry:
577; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[Y:%.*]], i64 [[I:%.*]]
578; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_noundef_arg(ptr [[GEP]])
579; CHECK-NEXT:    ret void
580;
581entry:
582  br i1 %X, label %if, label %else
583
584if:
585  br label %else
586
587else:
588  %phi = phi ptr [ %Y, %entry ], [ undef, %if ]
589  %gep = getelementptr i8, ptr %phi, i64 %I
590  call ptr @fn_noundef_arg(ptr %gep)
591  ret void
592}
593
594define void @test9_missing_noundef(i1 %X, ptr %Y) {
595; CHECK-LABEL: @test9_missing_noundef(
596; CHECK-NEXT:  entry:
597; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
598; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_arg(ptr [[SPEC_SELECT]])
599; CHECK-NEXT:    ret void
600;
601entry:
602  br i1 %X, label %if, label %else
603
604if:
605  br label %else
606
607else:
608  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
609  call ptr @fn_nonnull_arg(ptr %phi)
610  ret void
611}
612
613define void @test9_null_defined(i1 %X, ptr %Y) #0 {
614; CHECK-LABEL: @test9_null_defined(
615; CHECK-NEXT:  entry:
616; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]]
617; CHECK-NEXT:    [[TMP0:%.*]] = call ptr @fn_nonnull_noundef_arg(ptr [[SPEC_SELECT]])
618; CHECK-NEXT:    ret void
619;
620entry:
621  br i1 %X, label %if, label %else
622
623if:
624  br label %else
625
626else:
627  %phi = phi ptr [ %Y, %entry ], [ null, %if ]
628  call ptr @fn_nonnull_noundef_arg(ptr %phi)
629  ret void
630}
631
632define i32 @test_assume_false(i32 %cond) {
633; CHECK-LABEL: @test_assume_false(
634; CHECK-NEXT:  entry:
635; CHECK-NEXT:    switch i32 [[COND:%.*]], label [[DEFAULT:%.*]] [
636; CHECK-NEXT:      i32 0, label [[EXIT:%.*]]
637; CHECK-NEXT:      i32 1, label [[CASE1:%.*]]
638; CHECK-NEXT:      i32 2, label [[CASE2:%.*]]
639; CHECK-NEXT:    ]
640; CHECK:       case1:
641; CHECK-NEXT:    br label [[EXIT]]
642; CHECK:       case2:
643; CHECK-NEXT:    br label [[EXIT]]
644; CHECK:       default:
645; CHECK-NEXT:    unreachable
646; CHECK:       exit:
647; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ 2, [[CASE1]] ], [ 3, [[CASE2]] ], [ 1, [[ENTRY:%.*]] ]
648; CHECK-NEXT:    call void @llvm.assume(i1 true)
649; CHECK-NEXT:    ret i32 [[RES]]
650;
651entry:
652  switch i32 %cond, label %default [
653  i32 0, label %case0
654  i32 1, label %case1
655  i32 2, label %case2
656  ]
657
658case0:
659  br label %exit
660
661case1:
662  br label %exit
663
664case2:
665  br label %exit
666
667default:
668  br label %exit
669
670exit:
671  %bool = phi i1 [ false, %default ], [ true, %case0 ], [ true, %case1 ], [ true, %case2 ]
672  %res = phi i32 [ 0, %default ], [ 1, %case0 ], [ 2, %case1 ], [ 3, %case2 ]
673  call void @llvm.assume(i1 %bool)
674  ret i32 %res
675}
676
677define i32 @test_assume_undef(i32 %cond) {
678; CHECK-LABEL: @test_assume_undef(
679; CHECK-NEXT:  entry:
680; CHECK-NEXT:    switch i32 [[COND:%.*]], label [[DEFAULT:%.*]] [
681; CHECK-NEXT:      i32 0, label [[EXIT:%.*]]
682; CHECK-NEXT:      i32 1, label [[CASE1:%.*]]
683; CHECK-NEXT:      i32 2, label [[CASE2:%.*]]
684; CHECK-NEXT:    ]
685; CHECK:       case1:
686; CHECK-NEXT:    br label [[EXIT]]
687; CHECK:       case2:
688; CHECK-NEXT:    br label [[EXIT]]
689; CHECK:       default:
690; CHECK-NEXT:    unreachable
691; CHECK:       exit:
692; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ 2, [[CASE1]] ], [ 3, [[CASE2]] ], [ 1, [[ENTRY:%.*]] ]
693; CHECK-NEXT:    call void @llvm.assume(i1 true)
694; CHECK-NEXT:    ret i32 [[RES]]
695;
696entry:
697  switch i32 %cond, label %default [
698  i32 0, label %case0
699  i32 1, label %case1
700  i32 2, label %case2
701  ]
702
703case0:
704  br label %exit
705
706case1:
707  br label %exit
708
709case2:
710  br label %exit
711
712default:
713  br label %exit
714
715exit:
716  %bool = phi i1 [ undef, %default ], [ true, %case0 ], [ true, %case1 ], [ true, %case2 ]
717  %res = phi i32 [ 0, %default ], [ 1, %case0 ], [ 2, %case1 ], [ 3, %case2 ]
718  call void @llvm.assume(i1 %bool)
719  ret i32 %res
720}
721
722define i32 @test_assume_var(i32 %cond, i1 %var) {
723; CHECK-LABEL: @test_assume_var(
724; CHECK-NEXT:  entry:
725; CHECK-NEXT:    switch i32 [[COND:%.*]], label [[DEFAULT:%.*]] [
726; CHECK-NEXT:      i32 0, label [[EXIT:%.*]]
727; CHECK-NEXT:      i32 1, label [[CASE1:%.*]]
728; CHECK-NEXT:      i32 2, label [[CASE2:%.*]]
729; CHECK-NEXT:    ]
730; CHECK:       case1:
731; CHECK-NEXT:    br label [[EXIT]]
732; CHECK:       case2:
733; CHECK-NEXT:    br label [[EXIT]]
734; CHECK:       default:
735; CHECK-NEXT:    br label [[EXIT]]
736; CHECK:       exit:
737; CHECK-NEXT:    [[BOOL:%.*]] = phi i1 [ [[VAR:%.*]], [[DEFAULT]] ], [ true, [[CASE1]] ], [ true, [[CASE2]] ], [ true, [[ENTRY:%.*]] ]
738; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ 0, [[DEFAULT]] ], [ 2, [[CASE1]] ], [ 3, [[CASE2]] ], [ 1, [[ENTRY]] ]
739; CHECK-NEXT:    call void @llvm.assume(i1 [[BOOL]])
740; CHECK-NEXT:    ret i32 [[RES]]
741;
742entry:
743  switch i32 %cond, label %default [
744  i32 0, label %case0
745  i32 1, label %case1
746  i32 2, label %case2
747  ]
748
749case0:
750  br label %exit
751
752case1:
753  br label %exit
754
755case2:
756  br label %exit
757
758default:
759  br label %exit
760
761exit:
762  %bool = phi i1 [ %var, %default ], [ true, %case0 ], [ true, %case1 ], [ true, %case2 ]
763  %res = phi i32 [ 0, %default ], [ 1, %case0 ], [ 2, %case1 ], [ 3, %case2 ]
764  call void @llvm.assume(i1 %bool)
765  ret i32 %res
766}
767
768define i32 @test_assume_bundle_nonnull(i32 %cond, ptr nonnull %p) {
769; CHECK-LABEL: @test_assume_bundle_nonnull(
770; CHECK-NEXT:  entry:
771; CHECK-NEXT:    switch i32 [[COND:%.*]], label [[DEFAULT:%.*]] [
772; CHECK-NEXT:      i32 0, label [[EXIT:%.*]]
773; CHECK-NEXT:      i32 1, label [[CASE1:%.*]]
774; CHECK-NEXT:      i32 2, label [[CASE2:%.*]]
775; CHECK-NEXT:    ]
776; CHECK:       case1:
777; CHECK-NEXT:    br label [[EXIT]]
778; CHECK:       case2:
779; CHECK-NEXT:    br label [[EXIT]]
780; CHECK:       default:
781; CHECK-NEXT:    br label [[EXIT]]
782; CHECK:       exit:
783; CHECK-NEXT:    [[PTR:%.*]] = phi ptr [ null, [[DEFAULT]] ], [ [[P:%.*]], [[CASE1]] ], [ [[P]], [[CASE2]] ], [ [[P]], [[ENTRY:%.*]] ]
784; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ 0, [[DEFAULT]] ], [ 2, [[CASE1]] ], [ 3, [[CASE2]] ], [ 1, [[ENTRY]] ]
785; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[PTR]]) ]
786; CHECK-NEXT:    ret i32 [[RES]]
787;
788entry:
789  switch i32 %cond, label %default [
790  i32 0, label %case0
791  i32 1, label %case1
792  i32 2, label %case2
793  ]
794
795case0:
796  br label %exit
797
798case1:
799  br label %exit
800
801case2:
802  br label %exit
803
804default:
805  br label %exit
806
807exit:
808  %ptr = phi ptr [ null, %default ], [ %p, %case0 ], [ %p, %case1 ], [ %p, %case2 ]
809  %res = phi i32 [ 0, %default ], [ 1, %case0 ], [ 2, %case1 ], [ 3, %case2 ]
810  call void @llvm.assume(i1 true) [ "nonnull"(ptr %ptr) ]
811  ret i32 %res
812}
813
814define i32 @test_assume_bundle_align(i32 %cond, ptr nonnull %p) {
815; CHECK-LABEL: @test_assume_bundle_align(
816; CHECK-NEXT:  entry:
817; CHECK-NEXT:    switch i32 [[COND:%.*]], label [[DEFAULT:%.*]] [
818; CHECK-NEXT:      i32 0, label [[EXIT:%.*]]
819; CHECK-NEXT:      i32 1, label [[CASE1:%.*]]
820; CHECK-NEXT:      i32 2, label [[CASE2:%.*]]
821; CHECK-NEXT:    ]
822; CHECK:       case1:
823; CHECK-NEXT:    br label [[EXIT]]
824; CHECK:       case2:
825; CHECK-NEXT:    br label [[EXIT]]
826; CHECK:       default:
827; CHECK-NEXT:    br label [[EXIT]]
828; CHECK:       exit:
829; CHECK-NEXT:    [[PTR:%.*]] = phi ptr [ null, [[DEFAULT]] ], [ [[P:%.*]], [[CASE1]] ], [ [[P]], [[CASE2]] ], [ [[P]], [[ENTRY:%.*]] ]
830; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ 0, [[DEFAULT]] ], [ 2, [[CASE1]] ], [ 3, [[CASE2]] ], [ 1, [[ENTRY]] ]
831; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[PTR]], i32 8) ]
832; CHECK-NEXT:    ret i32 [[RES]]
833;
834entry:
835  switch i32 %cond, label %default [
836  i32 0, label %case0
837  i32 1, label %case1
838  i32 2, label %case2
839  ]
840
841case0:
842  br label %exit
843
844case1:
845  br label %exit
846
847case2:
848  br label %exit
849
850default:
851  br label %exit
852
853exit:
854  %ptr = phi ptr [ null, %default ], [ %p, %case0 ], [ %p, %case1 ], [ %p, %case2 ]
855  %res = phi i32 [ 0, %default ], [ 1, %case0 ], [ 2, %case1 ], [ 3, %case2 ]
856  call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i32 8) ]
857  ret i32 %res
858}
859
860; From bb to bb5 is UB.
861define i32 @test9_null_user_order_1(ptr %arg, i1 %arg1, ptr %arg2) {
862; CHECK-LABEL: @test9_null_user_order_1(
863; CHECK-NEXT:  bb:
864; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
865; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
866; CHECK-NEXT:    [[I:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
867; CHECK-NEXT:    [[I4:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 1
868; CHECK-NEXT:    store ptr [[I4]], ptr [[ARG]], align 8
869; CHECK-NEXT:    [[I7:%.*]] = load i32, ptr [[I]], align 4
870; CHECK-NEXT:    [[I8:%.*]] = icmp ne ptr [[I]], [[ARG2:%.*]]
871; CHECK-NEXT:    call void @fn_ptr_arg(i1 [[I8]])
872; CHECK-NEXT:    ret i32 [[I7]]
873;
874bb:
875  br i1 %arg1, label %bb5, label %bb3
876
877bb3:                                              ; preds = %bb
878  %i = load ptr, ptr %arg, align 8
879  %i4 = getelementptr inbounds i8, ptr %i, i64 1
880  store ptr %i4, ptr %arg, align 8
881  br label %bb5
882
883bb5:                                              ; preds = %bb3, %bb
884  %i6 = phi ptr [ %i, %bb3 ], [ null, %bb ]
885  %i7 = load i32, ptr %i6, align 4
886  %i8 = icmp ne ptr %i6, %arg2
887  call void @fn_ptr_arg(i1 %i8)
888  ret i32 %i7
889}
890
891define i32 @test9_null_user_order_2(ptr %arg, i1 %arg1, ptr %arg2) {
892; CHECK-LABEL: @test9_null_user_order_2(
893; CHECK-NEXT:  bb:
894; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
895; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP0]])
896; CHECK-NEXT:    [[I:%.*]] = load ptr, ptr [[ARG:%.*]], align 8
897; CHECK-NEXT:    [[I4:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 1
898; CHECK-NEXT:    store ptr [[I4]], ptr [[ARG]], align 8
899; CHECK-NEXT:    [[I8:%.*]] = icmp ne ptr [[I]], [[ARG2:%.*]]
900; CHECK-NEXT:    call void @fn_ptr_arg_nounwind_willreturn(i1 [[I8]])
901; CHECK-NEXT:    [[I7:%.*]] = load i32, ptr [[I]], align 4
902; CHECK-NEXT:    ret i32 [[I7]]
903;
904bb:
905  br i1 %arg1, label %bb5, label %bb3
906
907bb3:                                              ; preds = %bb
908  %i = load ptr, ptr %arg, align 8
909  %i4 = getelementptr inbounds i8, ptr %i, i64 1
910  store ptr %i4, ptr %arg, align 8
911  br label %bb5
912
913bb5:                                              ; preds = %bb3, %bb
914  %i6 = phi ptr [ %i, %bb3 ], [ null, %bb ]
915  %i8 = icmp ne ptr %i6, %arg2
916  call void @fn_ptr_arg_nounwind_willreturn(i1 %i8)
917  %i7 = load i32, ptr %i6, align 4
918  ret i32 %i7
919}
920
921declare void @side.effect()
922declare i8 @get.i8()
923
924define i8 @udiv_by_zero(i8 %x, i8 %i, i8 %v) {
925; CHECK-LABEL: @udiv_by_zero(
926; CHECK-NEXT:  entry:
927; CHECK-NEXT:    switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [
928; CHECK-NEXT:      i8 9, label [[SW_BB2:%.*]]
929; CHECK-NEXT:      i8 2, label [[RETURN:%.*]]
930; CHECK-NEXT:    ]
931; CHECK:       sw.bb2:
932; CHECK-NEXT:    br label [[RETURN]]
933; CHECK:       sw.default:
934; CHECK-NEXT:    br label [[RETURN]]
935; CHECK:       return:
936; CHECK-NEXT:    [[Y:%.*]] = phi i8 [ 9, [[SW_BB2]] ], [ [[V:%.*]], [[SW_DEFAULT]] ], [ 2, [[ENTRY:%.*]] ]
937; CHECK-NEXT:    [[R:%.*]] = udiv i8 [[X:%.*]], [[Y]]
938; CHECK-NEXT:    ret i8 [[R]]
939;
940entry:
941  switch i8 %i, label %sw.default [
942  i8 0, label %sw.bb0
943  i8 2, label %sw.bb1
944  i8 9, label %sw.bb2
945  ]
946
947sw.bb0:
948  br label %return
949
950sw.bb1:
951  br label %return
952sw.bb2:
953  br label %return
954sw.default:
955  br label %return
956
957return:
958  %y = phi i8 [ 0, %sw.bb0 ], [ 2, %sw.bb1 ], [ 9, %sw.bb2 ], [ %v, %sw.default ]
959  %r = udiv i8 %x, %y
960  ret i8 %r
961}
962
963define i8 @urem_by_zero(i8 %x, i8 %i, i8 %v) {
964; CHECK-LABEL: @urem_by_zero(
965; CHECK-NEXT:  entry:
966; CHECK-NEXT:    switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [
967; CHECK-NEXT:      i8 0, label [[RETURN:%.*]]
968; CHECK-NEXT:      i8 2, label [[SW_BB1:%.*]]
969; CHECK-NEXT:      i8 9, label [[SW_BB2:%.*]]
970; CHECK-NEXT:    ]
971; CHECK:       sw.bb1:
972; CHECK-NEXT:    br label [[RETURN]]
973; CHECK:       sw.bb2:
974; CHECK-NEXT:    br label [[RETURN]]
975; CHECK:       sw.default:
976; CHECK-NEXT:    unreachable
977; CHECK:       return:
978; CHECK-NEXT:    [[Y:%.*]] = phi i8 [ 2, [[SW_BB1]] ], [ 9, [[SW_BB2]] ], [ [[V:%.*]], [[ENTRY:%.*]] ]
979; CHECK-NEXT:    [[R:%.*]] = urem i8 [[X:%.*]], [[Y]]
980; CHECK-NEXT:    ret i8 [[R]]
981;
982entry:
983  switch i8 %i, label %sw.default [
984  i8 0, label %sw.bb0
985  i8 2, label %sw.bb1
986  i8 9, label %sw.bb2
987  ]
988
989sw.bb0:
990  br label %return
991
992sw.bb1:
993  br label %return
994sw.bb2:
995  br label %return
996sw.default:
997  br label %return
998
999return:
1000  %y = phi i8 [ %v, %sw.bb0 ], [ 2, %sw.bb1 ], [ 9, %sw.bb2 ], [ 0, %sw.default ]
1001  %r = urem i8 %x, %y
1002  ret i8 %r
1003}
1004
1005define i8 @udiv_of_zero_okay(i8 %x, i8 %i, i8 %v) {
1006; CHECK-LABEL: @udiv_of_zero_okay(
1007; CHECK-NEXT:  entry:
1008; CHECK-NEXT:    switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [
1009; CHECK-NEXT:      i8 0, label [[RETURN:%.*]]
1010; CHECK-NEXT:      i8 2, label [[SW_BB1:%.*]]
1011; CHECK-NEXT:      i8 9, label [[SW_BB2:%.*]]
1012; CHECK-NEXT:    ]
1013; CHECK:       sw.bb1:
1014; CHECK-NEXT:    br label [[RETURN]]
1015; CHECK:       sw.bb2:
1016; CHECK-NEXT:    br label [[RETURN]]
1017; CHECK:       sw.default:
1018; CHECK-NEXT:    br label [[RETURN]]
1019; CHECK:       return:
1020; CHECK-NEXT:    [[Y:%.*]] = phi i8 [ 2, [[SW_BB1]] ], [ 9, [[SW_BB2]] ], [ [[V:%.*]], [[SW_DEFAULT]] ], [ 0, [[ENTRY:%.*]] ]
1021; CHECK-NEXT:    [[R:%.*]] = udiv i8 [[Y]], [[X:%.*]]
1022; CHECK-NEXT:    ret i8 [[R]]
1023;
1024entry:
1025  switch i8 %i, label %sw.default [
1026  i8 0, label %sw.bb0
1027  i8 2, label %sw.bb1
1028  i8 9, label %sw.bb2
1029  ]
1030
1031sw.bb0:
1032  br label %return
1033
1034sw.bb1:
1035  br label %return
1036sw.bb2:
1037  br label %return
1038sw.default:
1039  br label %return
1040
1041return:
1042  %y = phi i8 [ 0, %sw.bb0 ], [ 2, %sw.bb1 ], [ 9, %sw.bb2 ], [ %v, %sw.default ]
1043  %r = udiv i8 %y, %x
1044  ret i8 %r
1045}
1046
1047define i8 @srem_by_zero(i8 %x, i8 %i) {
1048; CHECK-LABEL: @srem_by_zero(
1049; CHECK-NEXT:  entry:
1050; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[I:%.*]], 9
1051; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1052; CHECK:       if.then:
1053; CHECK-NEXT:    call void @side.effect()
1054; CHECK-NEXT:    unreachable
1055; CHECK:       if.else:
1056; CHECK-NEXT:    [[V:%.*]] = call i8 @get.i8()
1057; CHECK-NEXT:    [[R:%.*]] = srem i8 [[X:%.*]], [[V]]
1058; CHECK-NEXT:    ret i8 [[R]]
1059;
1060entry:
1061  %cmp = icmp ult i8 %i, 9
1062  br i1 %cmp, label %if.then, label %if.else
1063
1064if.then:
1065  call void @side.effect()
1066  br label %if.end
1067
1068if.else:
1069  %v = call i8 @get.i8()
1070  br label %if.end
1071
1072if.end:
1073  %y = phi i8 [ 0, %if.then ], [ %v, %if.else ]
1074  %r = srem i8 %x, %y
1075  ret i8 %r
1076}
1077
1078define i8 @srem_no_overflow_okay(i8 %i) {
1079; CHECK-LABEL: @srem_no_overflow_okay(
1080; CHECK-NEXT:  entry:
1081; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[I:%.*]], 9
1082; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1083; CHECK:       if.then:
1084; CHECK-NEXT:    call void @side.effect()
1085; CHECK-NEXT:    br label [[IF_END:%.*]]
1086; CHECK:       if.else:
1087; CHECK-NEXT:    [[V:%.*]] = call i8 @get.i8()
1088; CHECK-NEXT:    br label [[IF_END]]
1089; CHECK:       if.end:
1090; CHECK-NEXT:    [[Y:%.*]] = phi i8 [ -1, [[IF_THEN]] ], [ [[V]], [[IF_ELSE]] ]
1091; CHECK-NEXT:    [[R:%.*]] = srem i8 [[Y]], -128
1092; CHECK-NEXT:    ret i8 [[R]]
1093;
1094entry:
1095  %cmp = icmp ult i8 %i, 9
1096  br i1 %cmp, label %if.then, label %if.else
1097
1098if.then:
1099  call void @side.effect()
1100  br label %if.end
1101
1102if.else:
1103  %v = call i8 @get.i8()
1104  br label %if.end
1105
1106if.end:
1107  %y = phi i8 [ -1, %if.then ], [ %v, %if.else ]
1108  %r = srem i8 %y, 128
1109  ret i8 %r
1110}
1111
1112define i8 @sdiv_overflow_ub(i8 %i) {
1113; CHECK-LABEL: @sdiv_overflow_ub(
1114; CHECK-NEXT:  entry:
1115; CHECK-NEXT:    switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [
1116; CHECK-NEXT:      i8 0, label [[RETURN:%.*]]
1117; CHECK-NEXT:      i8 2, label [[SW_BB1:%.*]]
1118; CHECK-NEXT:      i8 9, label [[SW_BB2:%.*]]
1119; CHECK-NEXT:    ]
1120; CHECK:       sw.bb1:
1121; CHECK-NEXT:    [[V:%.*]] = call i8 @get.i8()
1122; CHECK-NEXT:    br label [[RETURN]]
1123; CHECK:       sw.bb2:
1124; CHECK-NEXT:    br label [[RETURN]]
1125; CHECK:       sw.default:
1126; CHECK-NEXT:    unreachable
1127; CHECK:       return:
1128; CHECK-NEXT:    [[Y:%.*]] = phi i8 [ [[V]], [[SW_BB1]] ], [ -1, [[SW_BB2]] ], [ 4, [[ENTRY:%.*]] ]
1129; CHECK-NEXT:    [[R:%.*]] = sdiv i8 -128, [[Y]]
1130; CHECK-NEXT:    ret i8 [[R]]
1131;
1132entry:
1133  switch i8 %i, label %sw.default [
1134  i8 0, label %sw.bb0
1135  i8 2, label %sw.bb1
1136  i8 9, label %sw.bb2
1137  ]
1138
1139sw.bb0:
1140  br label %return
1141sw.bb1:
1142  %v = call i8 @get.i8()
1143  br label %return
1144sw.bb2:
1145  br label %return
1146sw.default:
1147  unreachable
1148
1149return:
1150  %y = phi i8 [ 4, %sw.bb0 ], [ %v, %sw.bb1 ], [ -1, %sw.bb2 ]
1151  %r = sdiv i8 128, %y
1152  ret i8 %r
1153}
1154
1155define i8 @sdiv_overflow_ub_2x(i8 %i) {
1156; CHECK-LABEL: @sdiv_overflow_ub_2x(
1157; CHECK-NEXT:  entry:
1158; CHECK-NEXT:    switch i8 [[I:%.*]], label [[SW_DEFAULT:%.*]] [
1159; CHECK-NEXT:      i8 9, label [[RETURN:%.*]]
1160; CHECK-NEXT:      i8 2, label [[SW_BB1:%.*]]
1161; CHECK-NEXT:    ]
1162; CHECK:       sw.bb1:
1163; CHECK-NEXT:    [[V:%.*]] = call i8 @get.i8()
1164; CHECK-NEXT:    br label [[RETURN]]
1165; CHECK:       sw.default:
1166; CHECK-NEXT:    unreachable
1167; CHECK:       return:
1168; CHECK-NEXT:    [[Y:%.*]] = phi i8 [ [[V]], [[SW_BB1]] ], [ -1, [[ENTRY:%.*]] ]
1169; CHECK-NEXT:    [[R:%.*]] = sdiv i8 -128, [[Y]]
1170; CHECK-NEXT:    ret i8 [[R]]
1171;
1172entry:
1173  switch i8 %i, label %sw.default [
1174  i8 0, label %sw.bb0
1175  i8 2, label %sw.bb1
1176  i8 9, label %sw.bb2
1177  ]
1178
1179sw.bb0:
1180  br label %return
1181sw.bb1:
1182  %v = call i8 @get.i8()
1183  br label %return
1184sw.bb2:
1185  br label %return
1186sw.default:
1187  unreachable
1188
1189return:
1190  %y = phi i8 [ 0, %sw.bb0 ], [ %v, %sw.bb1 ], [ -1, %sw.bb2 ]
1191  %r = sdiv i8 128, %y
1192  ret i8 %r
1193}
1194
1195attributes #0 = { null_pointer_is_valid }
1196;.
1197; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
1198; CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
1199; CHECK: attributes #[[ATTR2:[0-9]+]] = { null_pointer_is_valid }
1200; CHECK: attributes #[[ATTR3:[0-9]+]] = { nounwind willreturn }
1201; CHECK: attributes #[[ATTR4]] = { nounwind }
1202;.
1203