Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / X86 / implicit-null-checks.mir
blob0077906b601810d19f681dbad25efe9baa64eeea
1 # RUN: llc -run-pass implicit-null-checks -mtriple=x86_64-apple-macosx -o - %s | FileCheck %s
3 --- |
4   target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
5   target triple = "x86_64-apple-macosx"
7   ;; Positive test
8   define i32 @imp_null_check_with_bitwise_op_0(ptr %x, i32 %val) {
9   entry:
10     br i1 undef, label %is_null, label %not_null, !make.implicit !0
12   is_null:
13     ret i32 42
15   not_null:
16     br i1 undef, label %ret_100, label %ret_200
18   ret_100:
19     ret i32 100
21   ret_200:
22     ret i32 200
23   }
25   ;; Negative test.  The regalloc is such that we cannot hoist the
26   ;; instruction materializing 2200000 into $eax
27   define i32 @imp_null_check_with_bitwise_op_1(ptr %x, i32 %val, ptr %ptr) {
28   entry:
29     br i1 undef, label %is_null, label %not_null, !make.implicit !0
31   is_null:
32     ret i32 undef
34   not_null:
35     br i1 undef, label %ret_100, label %ret_200
37   ret_100:
38     ret i32 100
40   ret_200:
41     ret i32 200
42   }
44   ;; Negative test: IR is identical to
45   ;; @imp_null_check_with_bitwise_op_0 but MIR differs.
46   define i32 @imp_null_check_with_bitwise_op_2(ptr %x, i32 %val) {
47   entry:
48     br i1 undef, label %is_null, label %not_null, !make.implicit !0
50   is_null:
51     ret i32 42
53   not_null:
54     br i1 undef, label %ret_100, label %ret_200
56   ret_100:
57     ret i32 100
59   ret_200:
60     ret i32 200
61   }
63   ;; Negative test: IR is identical to
64   ;; @imp_null_check_with_bitwise_op_0 but MIR differs.
65   define i32 @imp_null_check_with_bitwise_op_3(ptr %x, i32 %val) {
66   entry:
67     br i1 undef, label %is_null, label %not_null, !make.implicit !0
69   is_null:
70     ret i32 42
72   not_null:
73     br i1 undef, label %ret_100, label %ret_200
75   ret_100:
76     ret i32 100
78   ret_200:
79     ret i32 200
80   }
82   ;; Positive test
83   define i32 @imp_null_check_with_bitwise_op_4(ptr %x, i32 %val) {
84   entry:
85     br i1 undef, label %is_null, label %not_null, !make.implicit !0
87   is_null:
88     ret i32 42
90   not_null:
91     br i1 undef, label %ret_100, label %ret_200
93   ret_100:
94     ret i32 100
96   ret_200:
97     ret i32 200
98   }
100   declare void @f() readonly
102   define i32 @no_hoist_across_call(ptr %ptr) {
103   entry:
104     %is_null = icmp eq ptr %ptr, null
105     br i1 %is_null, label %leave, label %stay, !make.implicit !0
107   stay:
108     call void @f()
109     %val = load i32, ptr %ptr
110     ret i32 %val
112   leave:
113     ret i32 0
114   }
116   define i32 @dependency_live_in_hazard(ptr %ptr, ptr %ptr2, ptr %ptr3) #0 {
117   entry:
118     %val = load ptr, ptr %ptr2
119     %ptr_is_null = icmp eq ptr %ptr, null
120     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
122   not_null:                                         ; preds = %entry
123     %addend = load i32, ptr %val
124     %result = load i32, ptr %ptr
125     %result.shr = lshr i32 %result, 4
126     %result.and = and i32 %result.shr, 4095
127     %result.add = add i32 %addend, %result.and
128     ret i32 %result.add
130   is_null:                                          ; preds = %entry
131     ret i32 0
132   }
134   define i32 @use_alternate_load_op(ptr %ptr, ptr %ptr2) {
135   entry:
136     %ptr_is_null = icmp eq ptr %ptr, null
137     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
139   not_null:
140     ret i32 undef
142   is_null:
143     ret i32 0
144   }
146   define i32 @imp_null_check_gep_load_with_use_dep(ptr %x, i32 %a) {
147   entry:
148     %c = icmp eq ptr %x, null
149     br i1 %c, label %is_null, label %not_null, !make.implicit !0
150   
151   is_null:                                          ; preds = %entry
152     ret i32 42
153   
154   not_null:                                         ; preds = %entry
155     %x.loc = getelementptr i32, ptr %x, i32 1
156     %y = ptrtoint ptr %x.loc to i32
157     %b = add i32 %a, %y
158     %t = load i32, ptr %x
159     %z = add i32 %t, %b
160     ret i32 %z
161   }
163   define i32 @imp_null_check_load_with_base_sep(ptr %x, i32 %a) {
164   entry:
165     %c = icmp eq ptr %x, null
166     br i1 %c, label %is_null, label %not_null, !make.implicit !0
167   
168   is_null:                                          ; preds = %entry
169     ret i32 42
170   
171   not_null:                                         ; preds = %entry
172     ret i32 undef
173   }
175   define void @inc_store(ptr %ptr, i32 %val) {
176   entry:
177     %ptr_is_null = icmp eq ptr %ptr, null
178     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
180   not_null:
181     ret void
183   is_null:
184     ret void
185   }
187   define void @inc_store_plus_offset(ptr %ptr, i32 %val) {
188   entry:
189     %ptr_is_null = icmp eq ptr %ptr, null
190     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
192   not_null:
193     ret void
195   is_null:
196     ret void
197   }
199   define void @inc_store_with_dep(ptr %ptr, i32 %val) {
200   entry:
201     %ptr_is_null = icmp eq ptr %ptr, null
202     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
204   not_null:
205     ret void
207   is_null:
208     ret void
209   }
211   define i32 @inc_store_with_dep_in_null(ptr %ptr, i32 %val) {
212   entry:
213     %ptr_is_null = icmp eq ptr %ptr, null
214     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
216   not_null:
217     ret i32 undef
219   is_null:
220     ret i32 undef
221   }
223   define void @inc_store_with_volatile(ptr %ptr, i32 %val) {
224   entry:
225     %ptr_is_null = icmp eq ptr %ptr, null
226     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
228   not_null:
229     ret void
231   is_null:
232     ret void
233   }
235   define void @inc_store_with_two_dep(ptr %ptr, i32 %val) {
236   entry:
237     %ptr_is_null = icmp eq ptr %ptr, null
238     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
240   not_null:
241     ret void
243   is_null:
244     ret void
245   }
247   define void @inc_store_with_redefined_base(ptr %ptr, i32 %val) {
248   entry:
249     %ptr_is_null = icmp eq ptr %ptr, null
250     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
252   not_null:
253     ret void
255   is_null:
256     ret void
257   }
259   define i32 @inc_store_with_reused_base(ptr %ptr, i32 %val) {
260   entry:
261     %ptr_is_null = icmp eq ptr %ptr, null
262     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
264   not_null:
265     ret i32 undef
267   is_null:
268     ret i32 undef
269   }
271   define i32 @inc_store_across_call(ptr %ptr) {
272   entry:
273     %ptr_is_null = icmp eq ptr %ptr, null
274     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
276   not_null:
277     call void @f()
278     ret i32 undef
280   is_null:
281     ret i32 undef
282   }
284   define i32 @inc_store_with_dep_in_dep(ptr %ptr, i32 %val) {
285   entry:
286     %ptr_is_null = icmp eq ptr %ptr, null
287     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
289   not_null:
290     ret i32 undef
292   is_null:
293     ret i32 undef
294   }
296   define i32 @inc_store_with_load_over_store(ptr %ptr, ptr %ptr2) {
297   entry:
298     %ptr_is_null = icmp eq ptr %ptr, null
299     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
301   not_null:
302     ret i32 undef
304   is_null:
305     ret i32 undef
306   }
308   define i32 @inc_store_with_store_over_load(ptr %ptr, ptr %ptr2) {
309   entry:
310     %ptr_is_null = icmp eq ptr %ptr, null
311     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
313   not_null:
314     ret i32 undef
316   is_null:
317     ret i32 undef
318   }
320   define void @inc_store_with_store_over_store(ptr %ptr, ptr %ptr2) {
321   entry:
322     %ptr_is_null = icmp eq ptr %ptr, null
323     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
325   not_null:
326     ret void
328   is_null:
329     ret void
330   }
332   define void @inc_store_with_load_and_store(ptr %ptr, ptr %ptr2) {
333   entry:
334     %ptr_is_null = icmp eq ptr %ptr, null
335     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
337   not_null:
338     ret void
340   is_null:
341     ret void
342   }
344   define i32 @inc_store_and_load_no_alias(ptr noalias %ptr, ptr noalias %ptr2) {
345   entry:
346     %ptr_is_null = icmp eq ptr %ptr, null
347     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
349   not_null:
350     ret i32 undef
352   is_null:
353     ret i32 undef
354   }
356   define i32 @inc_store_and_load_alias(ptr %ptr, ptr %ptr2) {
357   entry:
358     %ptr_is_null = icmp eq ptr %ptr, null
359     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
361   not_null:
362     ret i32 undef
364   is_null:
365     ret i32 undef
366   }
368   define i32 @inc_spill_dep(ptr %ptr, i32 %val) {
369   entry:
370     %ptr_is_null = icmp eq ptr %ptr, null
371     br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
373   not_null:
374     ret i32 undef
376   is_null:
377     ret i32 undef
378   }
380   define i32 @imp_null_check_address_mul_overflow(ptr %x, i32 %a) {
381   entry:
382     %c = icmp eq ptr %x, null
383     br i1 %c, label %is_null, label %not_null, !make.implicit !0
384   
385   is_null:                                          ; preds = %entry
386     ret i32 42
387   
388   not_null:                                         ; preds = %entry
389     %y = ptrtoint ptr %x to i32
390     %y64 = zext i32 %y to i64
391     %b = mul i64 %y64, 9223372036854775807 ; 0X0FFFF.. i.e. 2^63 - 1
392     %z = trunc i64 %b to i32
393     ret i32 %z
394   }
396   attributes #0 = { "target-features"="+bmi,+bmi2" }
398   !0 = !{}
401 name:            imp_null_check_with_bitwise_op_0
402 # CHECK-LABEL: name:            imp_null_check_with_bitwise_op_0
403 alignment:       16
404 tracksRegLiveness: true
405 liveins:
406   - { reg: '$rdi' }
407   - { reg: '$esi' }
408 # CHECK:  bb.0.entry:
409 # CHECK:    $eax = MOV32ri 2200000
410 # CHECK-NEXT:    $eax = FAULTING_OP 1, %bb.3, {{[0-9]+}}, $eax, $rdi, 1, $noreg, 0, $noreg, implicit-def $eflags :: (load (s32) from %ir.x)
411 # CHECK-NEXT:    JMP_1 %bb.1
413 body:             |
414   bb.0.entry:
415     liveins: $esi, $rdi
417     TEST64rr $rdi, $rdi, implicit-def $eflags
418     JCC_1 %bb.3, 4, implicit $eflags
420   bb.1.not_null:
421     liveins: $esi, $rdi
423     $eax = MOV32ri 2200000
424     $eax = AND32rm killed $eax, killed $rdi, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.x)
425     CMP32rr killed $eax, killed $esi, implicit-def $eflags
426     JCC_1 %bb.4, 4, implicit $eflags
428   bb.2.ret_200:
429     $eax = MOV32ri 200
430     RET64 $eax
432   bb.3.is_null:
433     $eax = MOV32ri 42
434     RET64 $eax
436   bb.4.ret_100:
437     $eax = MOV32ri 100
438     RET64 $eax
442 name:            imp_null_check_with_bitwise_op_1
443 alignment:       16
444 tracksRegLiveness: true
445 liveins:
446   - { reg: '$rdi' }
447   - { reg: '$esi' }
448   - { reg: '$rdx' }
449 # CHECK: bb.0.entry:
450 # CHECK:    $eax = MOV32rm killed $rdx, 1, $noreg, 0, $noreg :: (volatile load (s32) from %ir.ptr)
451 # CHECK-NEXT:    TEST64rr $rdi, $rdi, implicit-def $eflags
452 # CHECK-NEXT:    JCC_1 %bb.3, 4, implicit $eflags
454 body:             |
455   bb.0.entry:
456     liveins: $esi, $rdi, $rdx
458     $eax = MOV32rm killed $rdx, 1, $noreg, 0, $noreg :: (volatile load (s32) from %ir.ptr)
459     TEST64rr $rdi, $rdi, implicit-def $eflags
460     JCC_1 %bb.3, 4, implicit $eflags
462   bb.1.not_null:
463     liveins: $esi, $rdi
465     $eax = MOV32ri 2200000
466     $eax = AND32rm killed $eax, killed $rdi, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.x)
467     CMP32rr killed $eax, killed $esi, implicit-def $eflags
468     JCC_1 %bb.4, 4, implicit $eflags
470   bb.2.ret_200:
472     $eax = MOV32ri 200
474   bb.3.is_null:
475     liveins: $eax, $ah, $al, $ax, $bh, $bl, $bp, $bpl, $bx, $eax, $ebp, $ebx, $rax, $rbp, $rbx, $r12, $r13, $r14, $r15, $r12b, $r13b, $r14b, $r15b, $r12d, $r13d, $r14d, $r15d, $r12w, $r13w, $r14w, $r15w
477     RET64 $eax
479   bb.4.ret_100:
480     $eax = MOV32ri 100
481     RET64 $eax
485 name:            imp_null_check_with_bitwise_op_2
486 # CHECK-LABEL: name:            imp_null_check_with_bitwise_op_2
487 alignment:       16
488 tracksRegLiveness: true
489 liveins:
490   - { reg: '$rdi' }
491   - { reg: '$esi' }
492 # CHECK:  bb.0.entry:
493 # CHECK:    TEST64rr $rdi, $rdi, implicit-def $eflags
494 # CHECK-NEXT:    JCC_1 %bb.3, 4, implicit $eflags
496 body:             |
497   bb.0.entry:
498     liveins: $esi, $rdi
500     TEST64rr $rdi, $rdi, implicit-def $eflags
501     JCC_1 %bb.3, 4, implicit $eflags
503   bb.1.not_null:
504     liveins: $esi, $rdi
506     $eax = MOV32ri 2200000
507     $eax = ADD32ri killed $eax, 100, implicit-def dead $eflags
508     $eax = AND32rm killed $eax, killed $rdi, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.x)
509     CMP32rr killed $eax, killed $esi, implicit-def $eflags
510     JCC_1 %bb.4, 4, implicit $eflags
512   bb.2.ret_200:
513     $eax = MOV32ri 200
514     RET64 $eax
516   bb.3.is_null:
517     $eax = MOV32ri 42
518     RET64 $eax
520   bb.4.ret_100:
521     $eax = MOV32ri 100
522     RET64 $eax
526 name:            imp_null_check_with_bitwise_op_3
527 # CHECK-LABEL: name:            imp_null_check_with_bitwise_op_3
528 alignment:       16
529 tracksRegLiveness: true
530 liveins:
531   - { reg: '$rdi' }
532   - { reg: '$rsi' }
533 # CHECK:  bb.0.entry:
534 # CHECK:    TEST64rr $rdi, $rdi, implicit-def $eflags
535 # CHECK-NEXT:    JCC_1 %bb.3, 4, implicit $eflags
537 body:             |
538   bb.0.entry:
539     liveins: $rsi, $rdi
541     TEST64rr $rdi, $rdi, implicit-def $eflags
542     JCC_1 %bb.3, 4, implicit $eflags
544   bb.1.not_null:
545     liveins: $rsi, $rdi
547     $rdi  = MOV64ri 5000
548     $rdi = AND64rm killed $rdi, killed $rdi, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.x)
549     CMP64rr killed $rdi, killed $rsi, implicit-def $eflags
550     JCC_1 %bb.4, 4, implicit $eflags
552   bb.2.ret_200:
553     $eax = MOV32ri 200
554     RET64 $eax
556   bb.3.is_null:
557     $eax = MOV32ri 42
558     RET64 $eax
560   bb.4.ret_100:
561     $eax = MOV32ri 100
562     RET64 $eax
566 name:            imp_null_check_with_bitwise_op_4
567 # CHECK-LABEL: name:            imp_null_check_with_bitwise_op_4
568 alignment:       16
569 tracksRegLiveness: true
570 liveins:
571   - { reg: '$rdi' }
572   - { reg: '$rsi' }
573 # CHECK:  bb.0.entry:
574 # CHECK:  $rbx = MOV64rr $rdx
575 # CHECK-NEXT:  $rbx = FAULTING_OP 1, %bb.3, {{[0-9]+}}, $rbx, $rdi, 1, $noreg, 0, $noreg, implicit-def $eflags :: (load (s32) from %ir.x)
577 body:             |
578   bb.0.entry:
579     liveins: $rsi, $rdi, $rdx
581     TEST64rr $rdi, $rdi, implicit-def $eflags
582     JCC_1 %bb.3, 4, implicit $eflags
584   bb.1.not_null:
585     liveins: $rsi, $rdi, $rdx
587     $rbx  = MOV64rr $rdx
588     $rbx = AND64rm killed $rbx, killed $rdi, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.x)
589     $rdx = MOV64ri 0
590     CMP64rr killed $rbx, killed $rsi, implicit-def $eflags
591     JCC_1 %bb.4, 4, implicit $eflags
593   bb.2.ret_200:
594     $eax = MOV32ri 200
595     RET64 $eax
597   bb.3.is_null:
598     $eax = MOV32ri 42
599     RET64 $eax
601   bb.4.ret_100:
602     $eax = MOV32ri 100
603     RET64 $eax
607 name:            no_hoist_across_call
608 # CHECK-LABEL: name:            no_hoist_across_call
609 alignment:       16
610 tracksRegLiveness: true
611 liveins:
612   - { reg: '$rdi' }
613 calleeSavedRegisters: [ '$bh', '$bl', '$bp', '$bpl', '$bx', '$ebp', '$ebx',
614                         '$rbp', '$rbx', '$r12', '$r13', '$r14', '$r15',
615                         '$r12b', '$r13b', '$r14b', '$r15b', '$r12d', '$r13d',
616                         '$r14d', '$r15d', '$r12w', '$r13w', '$r14w', '$r15w' ]
617 # CHECK: body:
618 # CHECK-NOT: FAULTING_OP
619 # CHECK: bb.1.stay:
620 # CHECK: CALL64pcrel32
621 body:             |
622   bb.0.entry:
623     liveins: $rdi, $rbx
625     frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
626     CFI_INSTRUCTION def_cfa_offset 16
627     CFI_INSTRUCTION offset $rbx, -16
628     $rbx = MOV64rr $rdi
629     TEST64rr $rbx, $rbx, implicit-def $eflags
630     JCC_1 %bb.2, 4, implicit killed $eflags
632   bb.1.stay:
633     liveins: $rbx
635     CALL64pcrel32 @f, csr_64, implicit $rsp, implicit-def $rsp
636     $eax = MOV32rm killed $rbx, 1, $noreg, 0, $noreg :: (load (s32) from %ir.ptr)
637     $rbx = POP64r implicit-def $rsp, implicit $rsp
638     RET64 $eax
640   bb.2.leave:
641     $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
642     $rbx = POP64r implicit-def $rsp, implicit $rsp
643     RET64 $eax
647 name:            dependency_live_in_hazard
648 # CHECK-LABEL: name:            dependency_live_in_hazard
649 # CHECK:   bb.0.entry:
650 # CHECK-NOT: FAULTING_OP
651 # CHECK: bb.1.not_null:
653 # Make sure that the BEXTR32rm instruction below is not used to emit
654 # an implicit null check -- hoisting it will require hosting the move
655 # to $esi and we cannot do that without clobbering the use of $rsi in
656 # the first instruction in bb.1.not_null.
657 alignment:       16
658 tracksRegLiveness: true
659 liveins:
660   - { reg: '$rdi' }
661   - { reg: '$rsi' }
662 body:             |
663   bb.0.entry:
664     liveins: $rdi, $rsi
666     TEST64rr $rdi, $rdi, implicit-def $eflags
667     JCC_1 %bb.2, 4, implicit killed $eflags
669   bb.1.not_null:
670     liveins: $rdi, $rsi
672     $rcx = MOV64rm killed $rsi, 1, $noreg, 0, $noreg :: (load (s64) from %ir.ptr2)
673     $esi = MOV32ri 3076
674     $eax = BEXTR32rm killed $rdi, 1, $noreg, 0, $noreg, killed $esi, implicit-def dead $eflags :: (load (s32) from %ir.ptr)
675     $eax = ADD32rm killed $eax, killed $rcx, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.val)
676     RET64 $eax
678   bb.2.is_null:
679     $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
680     RET64 $eax
684 name:            use_alternate_load_op
685 # CHECK-LABEL: name:            use_alternate_load_op
686 # CHECK: bb.0.entry:
687 # CHECK: $rax = FAULTING_OP 1, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 0, $noreg
688 # CHECK-NEXT: JMP_1 %bb.1
689 # CHECK: bb.1.not_null
691 alignment:       16
692 tracksRegLiveness: true
693 liveins:
694   - { reg: '$rdi' }
695   - { reg: '$rsi' }
696 body:             |
697   bb.0.entry:
698     liveins: $rdi, $rsi
700     TEST64rr $rdi, $rdi, implicit-def $eflags
701     JCC_1 %bb.2, 4, implicit killed $eflags
703   bb.1.not_null:
704     liveins: $rdi, $rsi
706     $rcx = MOV64rm killed $rsi, 1, $noreg, 0, $noreg
707     $rcx = AND64rm killed $rcx, $rdi, 1, $noreg, 0, $noreg, implicit-def dead $eflags
708     $rax = MOV64rm killed $rdi, 1, $noreg, 0, $noreg
709     RET64 $eax
711   bb.2.is_null:
712     $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
713     RET64 $eax
717 name:            imp_null_check_gep_load_with_use_dep
718 # CHECK-LABEL: name:            imp_null_check_gep_load_with_use_dep
719 # CHECK:  bb.0.entry:
720 # CHECK:    $eax = FAULTING_OP 1, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 0, $noreg, implicit-def $rax :: (load (s32) from %ir.x)
721 # CHECK-NEXT:    JMP_1 %bb.1
722 alignment:       16
723 tracksRegLiveness: true
724 liveins:         
725   - { reg: '$rdi' }
726   - { reg: '$rsi' }
727 body:             |
728   bb.0.entry:
729     liveins: $rsi, $rdi
730   
731     TEST64rr $rdi, $rdi, implicit-def $eflags
732     JCC_1 %bb.1, 4, implicit $eflags
733   
734   bb.2.not_null:
735     liveins: $rdi, $rsi
736   
737     $rsi = ADD64rr $rsi, $rdi, implicit-def dead $eflags
738     $eax = MOV32rm killed $rdi, 1, $noreg, 0, $noreg, implicit-def $rax :: (load (s32) from %ir.x)
739     $eax = LEA64_32r killed $rax, 1, killed $rsi, 4, $noreg
740     RET64 $eax
741   
742   bb.1.is_null:
743     $eax = MOV32ri 42
744     RET64 $eax
748 name:            imp_null_check_load_with_base_sep
749 # CHECK-LABEL: name:            imp_null_check_load_with_base_sep
750 # CHECK:  bb.0.entry:
751 # CHECK:     $rsi = ADD64rr $rsi, $rdi, implicit-def dead $eflags
752 # CHECK-NEXT:    $esi = FAULTING_OP 1, %bb.2, {{[0-9]+}}, $esi, $rdi, 1, $noreg, 0, $noreg, implicit-def $eflags
753 # CHECK-NEXT:    JMP_1 %bb.1
754 alignment:       16
755 tracksRegLiveness: true
756 liveins:         
757   - { reg: '$rdi' }
758   - { reg: '$rsi' }
759 body:             |
760   bb.0.entry:
761     liveins: $rsi, $rdi
762   
763     TEST64rr $rdi, $rdi, implicit-def $eflags
764     JCC_1 %bb.1, 4, implicit $eflags
765   
766   bb.2.not_null:
767     liveins: $rdi, $rsi
768   
769     $rsi = ADD64rr $rsi, $rdi, implicit-def dead $eflags
770     $esi = AND32rm killed $esi, $rdi, 1, $noreg, 0, $noreg, implicit-def dead $eflags
771     $eax = MOV32rr $esi
772     RET64 $eax
773   
774   bb.1.is_null:
775     $eax = MOV32ri 42
776     RET64 $eax
780 name:            inc_store
781 # CHECK-LABEL: name:            inc_store
782 # CHECK: bb.0.entry:
783 # CHECK:  $noreg = FAULTING_OP 3, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 0, $noreg, $rsi
784 # CHECK-NEXT: JMP_1 %bb.1
785 # CHECK: bb.1.not_null
787 alignment:       16
788 tracksRegLiveness: true
789 liveins:
790   - { reg: '$rdi' }
791   - { reg: '$rsi' }
792 body:             |
793   bb.0.entry:
794     liveins: $rdi, $rsi
796     TEST64rr $rdi, $rdi, implicit-def $eflags
797     JCC_1 %bb.2, 4, implicit killed $eflags
799   bb.1.not_null:
800     liveins: $rdi, $rsi
802     MOV64mr killed $rdi, 1, $noreg, 0, $noreg, killed $rsi
803     RET64
805   bb.2.is_null:
806     RET64
810 name:            inc_store_plus_offset
811 # CHECK-LABEL: inc_store_plus_offset
812 # CHECK: bb.0.entry:
813 # CHECK:  $noreg = FAULTING_OP 3, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 16, $noreg, $rsi
814 # CHECK-NEXT: JMP_1 %bb.1
815 # CHECK: bb.1.not_null
817 alignment:       16
818 tracksRegLiveness: true
819 liveins:
820   - { reg: '$rdi' }
821   - { reg: '$rsi' }
822 body:             |
823   bb.0.entry:
824     liveins: $rdi, $rsi
826     TEST64rr $rdi, $rdi, implicit-def $eflags
827     JCC_1 %bb.2, 4, implicit killed $eflags
829   bb.1.not_null:
830     liveins: $rdi, $rsi
832     MOV64mr killed $rdi, 1, $noreg, 16, $noreg, killed $rsi
833     RET64
835   bb.2.is_null:
836     RET64
840 name:            inc_store_with_dep
841 # CHECK-LABEL: inc_store_with_dep
842 # CHECK: bb.0.entry:
843 # CHECK:  $esi = ADD32rr killed $esi, killed $esi, implicit-def dead $eflags
844 # CHECK-NEXT:  $noreg = FAULTING_OP 3, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 16, $noreg, $esi
845 # CHECK-NEXT: JMP_1 %bb.1
846 # CHECK: bb.1.not_null
847 # CHECK-NOT: liveins: {{.*}} $eflags
849 alignment:       16
850 tracksRegLiveness: true
851 liveins:
852   - { reg: '$rdi' }
853   - { reg: '$rsi' }
854 body:             |
855   bb.0.entry:
856     liveins: $rdi, $rsi
858     TEST64rr $rdi, $rdi, implicit-def $eflags
859     JCC_1 %bb.2, 4, implicit killed $eflags
861   bb.1.not_null:
862     liveins: $rdi, $rsi
864     $esi = ADD32rr killed $esi, killed $esi, implicit-def dead $eflags
865     MOV32mr killed $rdi, 1, $noreg, 16, $noreg, killed $esi
866     RET64
868   bb.2.is_null:
869     RET64
873 name:            inc_store_with_dep_in_null
874 # CHECK-LABEL: inc_store_with_dep_in_null
875 # CHECK: bb.0.entry:
876 # CHECK:    TEST64rr $rdi, $rdi, implicit-def $eflags
877 # CHECK-NEXT:    JCC_1 %bb.2, 4, implicit killed $eflags
878 # CHECK: bb.1.not_null
880 alignment:       16
881 tracksRegLiveness: true
882 liveins:
883   - { reg: '$rdi' }
884   - { reg: '$rsi' }
885 body:             |
886   bb.0.entry:
887     liveins: $rdi, $rsi
889     TEST64rr $rdi, $rdi, implicit-def $eflags
890     JCC_1 %bb.2, 4, implicit killed $eflags
892   bb.1.not_null:
893     liveins: $rdi, $rsi
895     $esi = ADD32rr $esi, $esi, implicit-def dead $eflags
896     MOV32mr killed $rdi, 1, $noreg, 0, $noreg, $esi
897     $eax = MOV32rr killed $esi
898     RET64 $eax
900   bb.2.is_null:
901     liveins: $rsi
902     
903     $eax = MOV32rr killed $esi
904     RET64 $eax
908 name:            inc_store_with_volatile
909 # CHECK-LABEL: inc_store_with_volatile
910 # CHECK: bb.0.entry:
911 # CHECK:    TEST64rr $rdi, $rdi, implicit-def $eflags
912 # CHECK-NEXT:    JCC_1 %bb.2, 4, implicit killed $eflags
913 # CHECK: bb.1.not_null
915 alignment:       16
916 tracksRegLiveness: true
917 liveins:
918   - { reg: '$rdi' }
919   - { reg: '$rsi' }
920 body:             |
921   bb.0.entry:
922     liveins: $rdi, $rsi
924     TEST64rr $rdi, $rdi, implicit-def $eflags
925     JCC_1 %bb.2, 4, implicit killed $eflags
927   bb.1.not_null:
928     liveins: $rdi, $rsi
930     MOV32mr killed $rdi, 1, $noreg, 0, $noreg, killed $esi :: (volatile store (s32) into %ir.ptr)
931     RET64
933   bb.2.is_null:
934     RET64
938 name:            inc_store_with_two_dep
939 # CHECK-LABEL: inc_store_with_two_dep
940 # CHECK: bb.0.entry:
941 # CHECK:    TEST64rr $rdi, $rdi, implicit-def $eflags
942 # CHECK-NEXT:    JCC_1 %bb.2, 4, implicit killed $eflags
943 # CHECK: bb.1.not_null
945 alignment:       16
946 tracksRegLiveness: true
947 liveins:
948   - { reg: '$rdi' }
949   - { reg: '$rsi' }
950 body:             |
951   bb.0.entry:
952     liveins: $rdi, $rsi
954     TEST64rr $rdi, $rdi, implicit-def $eflags
955     JCC_1 %bb.2, 4, implicit killed $eflags
957   bb.1.not_null:
958     liveins: $rdi, $rsi
960     $esi = ADD32rr killed $esi, killed $esi, implicit-def dead $eflags
961     $esi = ADD32ri killed $esi, 15, implicit-def dead $eflags
962     MOV32mr killed $rdi, 1, $noreg, 16, $noreg, killed $esi
963     RET64
965   bb.2.is_null:
966     RET64
970 name:            inc_store_with_redefined_base
971 # CHECK-LABEL: inc_store_with_redefined_base
972 # CHECK: bb.0.entry:
973 # CHECK:    TEST64rr $rdi, $rdi, implicit-def $eflags
974 # CHECK-NEXT:    JCC_1 %bb.2, 4, implicit killed $eflags
975 # CHECK: bb.1.not_null
977 alignment:       16
978 tracksRegLiveness: true
979 liveins:
980   - { reg: '$rdi' }
981   - { reg: '$rsi' }
982 body:             |
983   bb.0.entry:
984     liveins: $rdi, $rsi
986     TEST64rr $rdi, $rdi, implicit-def $eflags
987     JCC_1 %bb.2, 4, implicit killed $eflags
989   bb.1.not_null:
990     liveins: $rdi, $rsi
992     $rdi = ADD64rr killed $rdi, killed $rdi, implicit-def dead $eflags
993     MOV32mr killed $rdi, 1, $noreg, 16, $noreg, killed $esi
994     RET64
996   bb.2.is_null:
997     RET64
1001 name:            inc_store_with_reused_base
1002 # CHECK-LABEL: inc_store_with_reused_base
1003 # CHECK: bb.0.entry:
1004 # CHECK:  $noreg = FAULTING_OP 3, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 16, $noreg, $esi
1005 # CHECK-NEXT: JMP_1 %bb.1
1006 # CHECK: bb.1.not_null
1008 alignment:       16
1009 tracksRegLiveness: true
1010 liveins:
1011   - { reg: '$rdi' }
1012   - { reg: '$rsi' }
1013 body:             |
1014   bb.0.entry:
1015     liveins: $rdi, $rsi
1017     TEST64rr $rdi, $rdi, implicit-def $eflags
1018     JCC_1 %bb.2, 4, implicit killed $eflags
1020   bb.1.not_null:
1021     liveins: $rdi, $rsi
1023     $rax = MOV64rr $rdi
1024     MOV32mr killed $rdi, 1, $noreg, 16, $noreg, killed $esi
1025     RET64 $eax
1027   bb.2.is_null:
1028     $rax = XOR64rr undef $rax, undef $rax, implicit-def dead $eflags
1029     RET64 $eax
1033 name:            inc_store_across_call
1034 # CHECK-LABEL: inc_store_across_call
1035 # CHECK: bb.0.entry:
1036 # CHECK:    TEST64rr $rbx, $rbx, implicit-def $eflags
1037 # CHECK-NEXT:    JCC_1 %bb.2, 4, implicit killed $eflags
1038 # CHECK: bb.1.not_null
1040 alignment:       16
1041 tracksRegLiveness: true
1042 liveins:
1043   - { reg: '$rdi' }
1044 calleeSavedRegisters: [ '$bh', '$bl', '$bp', '$bpl', '$bx', '$ebp', '$ebx',
1045                         '$rbp', '$rbx', '$r12', '$r13', '$r14', '$r15',
1046                         '$r12b', '$r13b', '$r14b', '$r15b', '$r12d', '$r13d',
1047                         '$r14d', '$r15d', '$r12w', '$r13w', '$r14w', '$r15w' ]
1048 body:             |
1049   bb.0.entry:
1050     liveins: $rdi, $rbx
1052     frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp
1053     CFI_INSTRUCTION def_cfa_offset 16
1054     CFI_INSTRUCTION offset $rbx, -16
1055     $rbx = MOV64rr killed $rdi
1056     TEST64rr $rbx, $rbx, implicit-def $eflags
1057     JCC_1 %bb.2, 4, implicit killed $eflags
1059   bb.1.not_null:
1060     liveins: $rbx
1062     CALL64pcrel32 @f, csr_64, implicit $rsp, implicit-def $rsp
1063     MOV32mi $rbx, 1, $noreg, 0, $noreg, 20
1064     $rax = MOV64rr killed $rbx
1065     $rbx = POP64r implicit-def $rsp, implicit $rsp
1066     RET64 $eax
1068   bb.2.is_null:
1069     $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
1070     $rbx = POP64r implicit-def $rsp, implicit $rsp
1071     RET64 $eax
1075 name:            inc_store_with_dep_in_dep
1076 # CHECK-LABEL: inc_store_with_dep_in_dep
1077 # CHECK: bb.0.entry:
1078 # CHECK:    TEST64rr $rdi, $rdi, implicit-def $eflags
1079 # CHECK-NEXT:    JCC_1 %bb.2, 4, implicit killed $eflags
1080 # CHECK: bb.1.not_null
1082 alignment:       16
1083 tracksRegLiveness: true
1084 liveins:
1085   - { reg: '$rdi' }
1086   - { reg: '$rsi' }
1087 body:             |
1088   bb.0.entry:
1089     liveins: $rdi, $rsi
1091     TEST64rr $rdi, $rdi, implicit-def $eflags
1092     JCC_1 %bb.2, 4, implicit killed $eflags
1094   bb.1.not_null:
1095     liveins: $rdi, $rsi
1097     $eax = MOV32rr $esi
1098     $esi = ADD32ri killed $esi, 15, implicit-def dead $eflags
1099     MOV32mr killed $rdi, 1, $noreg, 0, $noreg, killed $esi
1100     RET64 $eax
1102   bb.2.is_null:
1103     $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
1104     RET64 $eax
1108 name:            inc_store_with_load_over_store
1109 # CHECK-LABEL: inc_store_with_load_over_store
1110 # CHECK: bb.0.entry:
1111 # CHECK:    TEST64rr $rdi, $rdi, implicit-def $eflags
1112 # CHECK-NEXT:    JCC_1 %bb.2, 4, implicit killed $eflags
1113 # CHECK: bb.1.not_null
1115 alignment:       16
1116 tracksRegLiveness: true
1117 liveins:
1118   - { reg: '$rdi' }
1119   - { reg: '$rsi' }
1120 body:             |
1121   bb.0.entry:
1122     liveins: $rdi, $rsi
1124     TEST64rr $rdi, $rdi, implicit-def $eflags
1125     JCC_1 %bb.2, 4, implicit killed $eflags
1127   bb.1.not_null:
1128     liveins: $rdi, $rsi
1130     MOV32mi killed $rsi, 1, $noreg, 0, $noreg, 2
1131     $eax = MOV32rm killed $rdi, 1, $noreg, 0, $noreg 
1132     RET64 $eax
1134   bb.2.is_null:
1135     $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
1136     RET64 $eax
1140 name:            inc_store_with_store_over_load
1141 # CHECK-LABEL: inc_store_with_store_over_load
1142 # CHECK: bb.0.entry:
1143 # CHECK:    TEST64rr $rdi, $rdi, implicit-def $eflags
1144 # CHECK-NEXT:    JCC_1 %bb.2, 4, implicit killed $eflags
1145 # CHECK: bb.1.not_null
1147 alignment:       16
1148 tracksRegLiveness: true
1149 liveins:
1150   - { reg: '$rdi' }
1151   - { reg: '$rsi' }
1152 body:             |
1153   bb.0.entry:
1154     liveins: $rdi, $rsi
1156     TEST64rr $rdi, $rdi, implicit-def $eflags
1157     JCC_1 %bb.2, 4, implicit killed $eflags
1159   bb.1.not_null:
1160     liveins: $rdi, $rsi
1162     $eax = MOV32rm killed $rsi, 1, $noreg, 0, $noreg 
1163     MOV32mi killed $rdi, 1, $noreg, 0, $noreg, 2
1164     RET64 $eax
1166   bb.2.is_null:
1167     $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
1168     RET64 $eax
1172 name:            inc_store_with_store_over_store
1173 # CHECK-LABEL: inc_store_with_store_over_store
1174 # CHECK: bb.0.entry:
1175 # CHECK:    TEST64rr $rdi, $rdi, implicit-def $eflags
1176 # CHECK-NEXT:    JCC_1 %bb.2, 4, implicit killed $eflags
1177 # CHECK: bb.1.not_null
1179 alignment:       16
1180 tracksRegLiveness: true
1181 liveins:
1182   - { reg: '$rdi' }
1183   - { reg: '$rsi' }
1184 body:             |
1185   bb.0.entry:
1186     liveins: $rdi, $rsi
1188     TEST64rr $rdi, $rdi, implicit-def $eflags
1189     JCC_1 %bb.2, 4, implicit killed $eflags
1191   bb.1.not_null:
1192     liveins: $rdi, $rsi
1194     MOV32mi killed $rsi, 1, $noreg, 0, $noreg, 3 
1195     MOV32mi killed $rdi, 1, $noreg, 0, $noreg, 2
1196     RET64
1198   bb.2.is_null:
1199     RET64
1203 name:            inc_store_with_load_and_store
1204 # CHECK-LABEL: inc_store_with_load_and_store
1205 # CHECK: bb.0.entry:
1206 # CHECK:  $noreg = FAULTING_OP 2, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 0, $noreg, $esi, implicit-def $eflags
1207 # CHECK-NEXT: JMP_1 %bb.1
1208 # CHECK: bb.1.not_null
1210 alignment:       16
1211 tracksRegLiveness: true
1212 liveins:
1213   - { reg: '$rdi' }
1214   - { reg: '$rsi' }
1215 body:             |
1216   bb.0.entry:
1217     liveins: $rdi, $rsi
1219     TEST64rr $rdi, $rdi, implicit-def $eflags
1220     JCC_1 %bb.2, 4, implicit killed $eflags
1222   bb.1.not_null:
1223     liveins: $rdi, $rsi
1225     $esi = ADD32rr $esi, $esi, implicit-def dead $eflags
1226     ADD32mr killed $rdi, 1, $noreg, 0, $noreg, killed $esi, implicit-def dead $eflags
1227     RET64
1229   bb.2.is_null:
1230     RET64
1234 name:            inc_store_and_load_no_alias
1235 # CHECK-LABEL: inc_store_and_load_no_alias
1236 # CHECK: bb.0.entry:
1237 # CHECK:  $eax = FAULTING_OP 1, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 0, $noreg :: (load (s32) from %ir.ptr)
1238 # CHECK-NEXT: JMP_1 %bb.1
1239 # CHECK: bb.1.not_null
1241 alignment:       16
1242 tracksRegLiveness: true
1243 liveins:
1244   - { reg: '$rdi' }
1245   - { reg: '$rsi' }
1246 body:             |
1247   bb.0.entry:
1248     liveins: $rdi, $rsi
1250     TEST64rr $rdi, $rdi, implicit-def $eflags
1251     JCC_1 %bb.2, 4, implicit killed $eflags
1253   bb.1.not_null:
1254     liveins: $rdi, $rsi
1256     MOV32mi killed $rsi, 1, $noreg, 0, $noreg, 3 :: (store (s32) into %ir.ptr2)
1257     $eax = MOV32rm killed $rdi, 1, $noreg, 0, $noreg :: (load (s32) from %ir.ptr)
1258     RET64 $eax
1260   bb.2.is_null:
1261     $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
1262     RET64 $eax
1266 name:            inc_store_and_load_alias
1267 # CHECK-LABEL: inc_store_and_load_alias
1268 # CHECK: bb.0.entry:
1269 # CHECK:    TEST64rr $rdi, $rdi, implicit-def $eflags
1270 # CHECK-NEXT:    JCC_1 %bb.2, 4, implicit killed $eflags
1271 # CHECK: bb.1.not_null
1273 alignment:       16
1274 tracksRegLiveness: true
1275 liveins:
1276   - { reg: '$rdi' }
1277   - { reg: '$rsi' }
1278 body:             |
1279   bb.0.entry:
1280     liveins: $rdi, $rsi
1282     TEST64rr $rdi, $rdi, implicit-def $eflags
1283     JCC_1 %bb.2, 4, implicit killed $eflags
1285   bb.1.not_null:
1286     liveins: $rdi, $rsi
1288     MOV32mi killed $rsi, 1, $noreg, 0, $noreg, 3 :: (store (s32) into %ir.ptr2)
1289     $eax = MOV32rm killed $rdi, 1, $noreg, 0, $noreg :: (load (s32) from %ir.ptr)
1290     RET64 $eax
1292   bb.2.is_null:
1293     $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
1294     RET64 $eax
1298 name:            inc_spill_dep
1299 # CHECK-LABEL: inc_spill_dep
1300 # CHECK: bb.0.entry:
1301 # CHECK:    TEST64rr $rdi, $rdi, implicit-def $eflags
1302 # CHECK-NEXT:    JCC_1 %bb.2, 4, implicit killed $eflags
1303 # CHECK: bb.1.not_null
1305 alignment:       16
1306 tracksRegLiveness: true
1307 stack:
1308   - { id: 0, type: spill-slot, offset: -8, size: 8, alignment: 8}
1309 liveins:
1310   - { reg: '$rdi' }
1311   - { reg: '$rsi' }
1312 body:             |
1313   bb.0.entry:
1314     liveins: $rdi, $rsi
1316     $rsp = frame-setup SUB64ri8 $rsp, 8, implicit-def dead $eflags
1317     MOV32mr $rsp, 1, $noreg, 0, $noreg, $esi :: (store (s32) into %stack.0)
1318     TEST64rr $rdi, $rdi, implicit-def $eflags
1319     JCC_1 %bb.2, 4, implicit killed $eflags
1321   bb.1.not_null:
1322     liveins: $rdi, $rsi
1324     $r14d = MOV32rm $rsp, 1, $noreg, 0, $noreg :: (load (s32) from %stack.0)
1325     MOV64mr $rsp, 1, $noreg, 0, $noreg, $rdi :: (store (s64) into %stack.0)
1326     $edi = MOV32rm $rdi, 1, $noreg, 8, $noreg :: (load (s32) from %ir.ptr)
1327     $eax = MOV32rr $edi
1328     RET64 $eax
1330   bb.2.is_null:
1331     $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
1332     RET64 $eax
1336 name:            imp_null_check_address_mul_overflow
1337 # CHECK-LABEL: name:            imp_null_check_address_mul_overflow
1338 # CHECK:  bb.0.entry:
1339 # CHECK-NOT: FAULTING_OP
1340 alignment:       16
1341 tracksRegLiveness: true
1342 liveins:         
1343   - { reg: '$rdi' }
1344   - { reg: '$rsi' }
1345 body:             |
1346   bb.0.entry:
1347     liveins: $rsi, $rdi
1348   
1349     TEST64rr $rdi, $rdi, implicit-def $eflags
1350     JCC_1 %bb.1, 4, implicit $eflags
1351   
1352   bb.2.not_null:
1353     liveins: $rdi, $rsi
1354   
1355     $rcx = MOV64ri -9223372036854775808
1356     $eax = MOV32rm killed $rdi, 2, $rcx, 0, $noreg, implicit-def $rax
1357     RET64 $eax
1358   
1359   bb.1.is_null:
1360     $eax = MOV32ri 42
1361     RET64 $eax