1# RUN: llc -run-pass implicit-null-checks -mtriple=x86_64-apple-macosx -o - %s | FileCheck %s
2
3--- |
4  target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
5  target triple = "x86_64-apple-macosx"
6
7  ;; Positive test
8  define i32 @imp_null_check_with_bitwise_op_0(i32* %x, i32 %val) {
9  entry:
10    br i1 undef, label %is_null, label %not_null, !make.implicit !0
11
12  is_null:
13    ret i32 42
14
15  not_null:
16    br i1 undef, label %ret_100, label %ret_200
17
18  ret_100:
19    ret i32 100
20
21  ret_200:
22    ret i32 200
23  }
24
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(i32* %x, i32 %val, i32* %ptr) {
28  entry:
29    br i1 undef, label %is_null, label %not_null, !make.implicit !0
30
31  is_null:
32    ret i32 undef
33
34  not_null:
35    br i1 undef, label %ret_100, label %ret_200
36
37  ret_100:
38    ret i32 100
39
40  ret_200:
41    ret i32 200
42  }
43
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(i32* %x, i32 %val) {
47  entry:
48    br i1 undef, label %is_null, label %not_null, !make.implicit !0
49
50  is_null:
51    ret i32 42
52
53  not_null:
54    br i1 undef, label %ret_100, label %ret_200
55
56  ret_100:
57    ret i32 100
58
59  ret_200:
60    ret i32 200
61  }
62
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(i32* %x, i32 %val) {
66  entry:
67    br i1 undef, label %is_null, label %not_null, !make.implicit !0
68
69  is_null:
70    ret i32 42
71
72  not_null:
73    br i1 undef, label %ret_100, label %ret_200
74
75  ret_100:
76    ret i32 100
77
78  ret_200:
79    ret i32 200
80  }
81
82  ;; Positive test
83  define i32 @imp_null_check_with_bitwise_op_4(i32* %x, i32 %val) {
84  entry:
85    br i1 undef, label %is_null, label %not_null, !make.implicit !0
86
87  is_null:
88    ret i32 42
89
90  not_null:
91    br i1 undef, label %ret_100, label %ret_200
92
93  ret_100:
94    ret i32 100
95
96  ret_200:
97    ret i32 200
98  }
99
100  declare void @f() readonly
101
102  define i32 @no_hoist_across_call(i32* %ptr) {
103  entry:
104    %is_null = icmp eq i32* %ptr, null
105    br i1 %is_null, label %leave, label %stay, !make.implicit !0
106
107  stay:
108    call void @f()
109    %val = load i32, i32* %ptr
110    ret i32 %val
111
112  leave:
113    ret i32 0
114  }
115
116  define i32 @dependency_live_in_hazard(i32* %ptr, i32** %ptr2, i32* %ptr3) #0 {
117  entry:
118    %val = load i32*, i32** %ptr2
119    %ptr_is_null = icmp eq i32* %ptr, null
120    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
121
122  not_null:                                         ; preds = %entry
123    %addend = load i32, i32* %val
124    %result = load i32, i32* %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
129
130  is_null:                                          ; preds = %entry
131    ret i32 0
132  }
133
134  define i32 @use_alternate_load_op(i32* %ptr, i32* %ptr2) {
135  entry:
136    %ptr_is_null = icmp eq i32* %ptr, null
137    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
138
139  not_null:
140    ret i32 undef
141
142  is_null:
143    ret i32 0
144  }
145
146  define i32 @imp_null_check_gep_load_with_use_dep(i32* %x, i32 %a) {
147  entry:
148    %c = icmp eq i32* %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, i32* %x, i32 1
156    %y = ptrtoint i32* %x.loc to i32
157    %b = add i32 %a, %y
158    %t = load i32, i32* %x
159    %z = add i32 %t, %b
160    ret i32 %z
161  }
162
163  define i32 @imp_null_check_load_with_base_sep(i32* %x, i32 %a) {
164  entry:
165    %c = icmp eq i32* %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  }
174
175  define void @inc_store(i32* %ptr, i32 %val) {
176  entry:
177    %ptr_is_null = icmp eq i32* %ptr, null
178    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
179
180  not_null:
181    ret void
182
183  is_null:
184    ret void
185  }
186
187  define void @inc_store_plus_offset(i32* %ptr, i32 %val) {
188  entry:
189    %ptr_is_null = icmp eq i32* %ptr, null
190    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
191
192  not_null:
193    ret void
194
195  is_null:
196    ret void
197  }
198
199  define void @inc_store_with_dep(i32* %ptr, i32 %val) {
200  entry:
201    %ptr_is_null = icmp eq i32* %ptr, null
202    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
203
204  not_null:
205    ret void
206
207  is_null:
208    ret void
209  }
210
211  define i32 @inc_store_with_dep_in_null(i32* %ptr, i32 %val) {
212  entry:
213    %ptr_is_null = icmp eq i32* %ptr, null
214    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
215
216  not_null:
217    ret i32 undef
218
219  is_null:
220    ret i32 undef
221  }
222
223  define void @inc_store_with_volatile(i32* %ptr, i32 %val) {
224  entry:
225    %ptr_is_null = icmp eq i32* %ptr, null
226    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
227
228  not_null:
229    ret void
230
231  is_null:
232    ret void
233  }
234
235  define void @inc_store_with_two_dep(i32* %ptr, i32 %val) {
236  entry:
237    %ptr_is_null = icmp eq i32* %ptr, null
238    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
239
240  not_null:
241    ret void
242
243  is_null:
244    ret void
245  }
246
247  define void @inc_store_with_redefined_base(i32* %ptr, i32 %val) {
248  entry:
249    %ptr_is_null = icmp eq i32* %ptr, null
250    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
251
252  not_null:
253    ret void
254
255  is_null:
256    ret void
257  }
258
259  define i32 @inc_store_with_reused_base(i32* %ptr, i32 %val) {
260  entry:
261    %ptr_is_null = icmp eq i32* %ptr, null
262    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
263
264  not_null:
265    ret i32 undef
266
267  is_null:
268    ret i32 undef
269  }
270
271  define i32 @inc_store_across_call(i32* %ptr) {
272  entry:
273    %ptr_is_null = icmp eq i32* %ptr, null
274    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
275
276  not_null:
277    call void @f()
278    ret i32 undef
279
280  is_null:
281    ret i32 undef
282  }
283
284  define i32 @inc_store_with_dep_in_dep(i32* %ptr, i32 %val) {
285  entry:
286    %ptr_is_null = icmp eq i32* %ptr, null
287    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
288
289  not_null:
290    ret i32 undef
291
292  is_null:
293    ret i32 undef
294  }
295
296  define i32 @inc_store_with_load_over_store(i32* %ptr, i32* %ptr2) {
297  entry:
298    %ptr_is_null = icmp eq i32* %ptr, null
299    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
300
301  not_null:
302    ret i32 undef
303
304  is_null:
305    ret i32 undef
306  }
307
308  define i32 @inc_store_with_store_over_load(i32* %ptr, i32* %ptr2) {
309  entry:
310    %ptr_is_null = icmp eq i32* %ptr, null
311    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
312
313  not_null:
314    ret i32 undef
315
316  is_null:
317    ret i32 undef
318  }
319
320  define void @inc_store_with_store_over_store(i32* %ptr, i32* %ptr2) {
321  entry:
322    %ptr_is_null = icmp eq i32* %ptr, null
323    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
324
325  not_null:
326    ret void
327
328  is_null:
329    ret void
330  }
331
332  define void @inc_store_with_load_and_store(i32* %ptr, i32* %ptr2) {
333  entry:
334    %ptr_is_null = icmp eq i32* %ptr, null
335    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
336
337  not_null:
338    ret void
339
340  is_null:
341    ret void
342  }
343
344  define i32 @inc_store_and_load_no_alias(i32* noalias %ptr, i32* noalias %ptr2) {
345  entry:
346    %ptr_is_null = icmp eq i32* %ptr, null
347    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
348
349  not_null:
350    ret i32 undef
351
352  is_null:
353    ret i32 undef
354  }
355
356  define i32 @inc_store_and_load_alias(i32* %ptr, i32* %ptr2) {
357  entry:
358    %ptr_is_null = icmp eq i32* %ptr, null
359    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
360
361  not_null:
362    ret i32 undef
363
364  is_null:
365    ret i32 undef
366  }
367
368  define i32 @inc_spill_dep(i32* %ptr, i32 %val) {
369  entry:
370    %ptr_is_null = icmp eq i32* %ptr, null
371    br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0
372
373  not_null:
374    ret i32 undef
375
376  is_null:
377    ret i32 undef
378  }
379
380  attributes #0 = { "target-features"="+bmi,+bmi2" }
381
382  !0 = !{}
383...
384---
385name:            imp_null_check_with_bitwise_op_0
386# CHECK-LABEL: name:            imp_null_check_with_bitwise_op_0
387alignment:       4
388tracksRegLiveness: true
389liveins:
390  - { reg: '%rdi' }
391  - { reg: '%esi' }
392# CHECK:  bb.0.entry:
393# CHECK:    %eax = MOV32ri 2200000
394# CHECK-NEXT:    %eax = FAULTING_OP 1, %bb.3.is_null, {{[0-9]+}}, %eax, %rdi, 1, _, 0, _, implicit-def %eflags :: (load 4 from %ir.x)
395# CHECK-NEXT:    JMP_1 %bb.1.not_null
396
397body:             |
398  bb.0.entry:
399    liveins: %esi, %rdi
400
401    TEST64rr %rdi, %rdi, implicit-def %eflags
402    JE_1 %bb.3.is_null, implicit %eflags
403
404  bb.1.not_null:
405    liveins: %esi, %rdi
406
407    %eax = MOV32ri 2200000
408    %eax = AND32rm killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x)
409    CMP32rr killed %eax, killed %esi, implicit-def %eflags
410    JE_1 %bb.4.ret_100, implicit %eflags
411
412  bb.2.ret_200:
413    %eax = MOV32ri 200
414    RETQ %eax
415
416  bb.3.is_null:
417    %eax = MOV32ri 42
418    RETQ %eax
419
420  bb.4.ret_100:
421    %eax = MOV32ri 100
422    RETQ %eax
423
424...
425---
426name:            imp_null_check_with_bitwise_op_1
427alignment:       4
428tracksRegLiveness: true
429liveins:
430  - { reg: '%rdi' }
431  - { reg: '%esi' }
432  - { reg: '%rdx' }
433# CHECK: bb.0.entry:
434# CHECK:    %eax = MOV32rm killed %rdx, 1, _, 0, _ :: (volatile load 4 from %ir.ptr)
435# CHECK-NEXT:    TEST64rr %rdi, %rdi, implicit-def %eflags
436# CHECK-NEXT:    JE_1 %bb.3.is_null, implicit %eflags
437
438body:             |
439  bb.0.entry:
440    liveins: %esi, %rdi, %rdx
441
442    %eax = MOV32rm killed %rdx, 1, _, 0, _ :: (volatile load 4 from %ir.ptr)
443    TEST64rr %rdi, %rdi, implicit-def %eflags
444    JE_1 %bb.3.is_null, implicit %eflags
445
446  bb.1.not_null:
447    liveins: %esi, %rdi
448
449    %eax = MOV32ri 2200000
450    %eax = AND32rm killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x)
451    CMP32rr killed %eax, killed %esi, implicit-def %eflags
452    JE_1 %bb.4.ret_100, implicit %eflags
453
454  bb.2.ret_200:
455
456    %eax = MOV32ri 200
457
458  bb.3.is_null:
459    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
460
461    RETQ %eax
462
463  bb.4.ret_100:
464    %eax = MOV32ri 100
465    RETQ %eax
466
467...
468---
469name:            imp_null_check_with_bitwise_op_2
470# CHECK-LABEL: name:            imp_null_check_with_bitwise_op_2
471alignment:       4
472tracksRegLiveness: true
473liveins:
474  - { reg: '%rdi' }
475  - { reg: '%esi' }
476# CHECK:  bb.0.entry:
477# CHECK:    TEST64rr %rdi, %rdi, implicit-def %eflags
478# CHECK-NEXT:    JE_1 %bb.3.is_null, implicit %eflags
479
480body:             |
481  bb.0.entry:
482    liveins: %esi, %rdi
483
484    TEST64rr %rdi, %rdi, implicit-def %eflags
485    JE_1 %bb.3.is_null, implicit %eflags
486
487  bb.1.not_null:
488    liveins: %esi, %rdi
489
490    %eax = MOV32ri 2200000
491    %eax = ADD32ri killed %eax, 100, implicit-def dead %eflags
492    %eax = AND32rm killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x)
493    CMP32rr killed %eax, killed %esi, implicit-def %eflags
494    JE_1 %bb.4.ret_100, implicit %eflags
495
496  bb.2.ret_200:
497    %eax = MOV32ri 200
498    RETQ %eax
499
500  bb.3.is_null:
501    %eax = MOV32ri 42
502    RETQ %eax
503
504  bb.4.ret_100:
505    %eax = MOV32ri 100
506    RETQ %eax
507
508...
509---
510name:            imp_null_check_with_bitwise_op_3
511# CHECK-LABEL: name:            imp_null_check_with_bitwise_op_3
512alignment:       4
513tracksRegLiveness: true
514liveins:
515  - { reg: '%rdi' }
516  - { reg: '%rsi' }
517# CHECK:  bb.0.entry:
518# CHECK:    TEST64rr %rdi, %rdi, implicit-def %eflags
519# CHECK-NEXT:    JE_1 %bb.3.is_null, implicit %eflags
520
521body:             |
522  bb.0.entry:
523    liveins: %rsi, %rdi
524
525    TEST64rr %rdi, %rdi, implicit-def %eflags
526    JE_1 %bb.3.is_null, implicit %eflags
527
528  bb.1.not_null:
529    liveins: %rsi, %rdi
530
531    %rdi  = MOV64ri 5000
532    %rdi = AND64rm killed %rdi, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x)
533    CMP64rr killed %rdi, killed %rsi, implicit-def %eflags
534    JE_1 %bb.4.ret_100, implicit %eflags
535
536  bb.2.ret_200:
537    %eax = MOV32ri 200
538    RETQ %eax
539
540  bb.3.is_null:
541    %eax = MOV32ri 42
542    RETQ %eax
543
544  bb.4.ret_100:
545    %eax = MOV32ri 100
546    RETQ %eax
547
548...
549---
550name:            imp_null_check_with_bitwise_op_4
551# CHECK-LABEL: name:            imp_null_check_with_bitwise_op_4
552alignment:       4
553tracksRegLiveness: true
554liveins:
555  - { reg: '%rdi' }
556  - { reg: '%rsi' }
557# CHECK:  bb.0.entry:
558# CHECK:  %rbx = MOV64rr %rdx
559# CHECK-NEXT:  %rbx = FAULTING_OP 1, %bb.3.is_null, {{[0-9]+}}, %rbx, %rdi, 1, _, 0, _, implicit-def %eflags :: (load 4 from %ir.x)
560
561body:             |
562  bb.0.entry:
563    liveins: %rsi, %rdi, %rdx
564
565    TEST64rr %rdi, %rdi, implicit-def %eflags
566    JE_1 %bb.3.is_null, implicit %eflags
567
568  bb.1.not_null:
569    liveins: %rsi, %rdi, %rdx
570
571    %rbx  = MOV64rr %rdx
572    %rbx = AND64rm killed %rbx, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x)
573    %rdx = MOV64ri 0
574    CMP64rr killed %rbx, killed %rsi, implicit-def %eflags
575    JE_1 %bb.4.ret_100, implicit %eflags
576
577  bb.2.ret_200:
578    %eax = MOV32ri 200
579    RETQ %eax
580
581  bb.3.is_null:
582    %eax = MOV32ri 42
583    RETQ %eax
584
585  bb.4.ret_100:
586    %eax = MOV32ri 100
587    RETQ %eax
588
589...
590---
591name:            no_hoist_across_call
592# CHECK-LABEL: name:            no_hoist_across_call
593alignment:       4
594tracksRegLiveness: true
595liveins:
596  - { reg: '%rdi' }
597calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx',
598                        '%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15',
599                        '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d',
600                        '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ]
601# CHECK: body:
602# CHECK-NOT: FAULTING_OP
603# CHECK: bb.1.stay:
604# CHECK: CALL64pcrel32
605body:             |
606  bb.0.entry:
607    liveins: %rdi, %rbx
608
609    frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp
610    CFI_INSTRUCTION def_cfa_offset 16
611    CFI_INSTRUCTION offset %rbx, -16
612    %rbx = MOV64rr %rdi
613    TEST64rr %rbx, %rbx, implicit-def %eflags
614    JE_1 %bb.2.leave, implicit killed %eflags
615
616  bb.1.stay:
617    liveins: %rbx
618
619    CALL64pcrel32 @f, csr_64, implicit %rsp, implicit-def %rsp
620    %eax = MOV32rm killed %rbx, 1, _, 0, _ :: (load 4 from %ir.ptr)
621    %rbx = POP64r implicit-def %rsp, implicit %rsp
622    RETQ %eax
623
624  bb.2.leave:
625    %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags
626    %rbx = POP64r implicit-def %rsp, implicit %rsp
627    RETQ %eax
628
629...
630---
631name:            dependency_live_in_hazard
632# CHECK-LABEL: name:            dependency_live_in_hazard
633# CHECK:   bb.0.entry:
634# CHECK-NOT: FAULTING_OP
635# CHECK: bb.1.not_null:
636
637# Make sure that the BEXTR32rm instruction below is not used to emit
638# an implicit null check -- hoisting it will require hosting the move
639# to %esi and we cannot do that without clobbering the use of %rsi in
640# the first instruction in bb.1.not_null.
641alignment:       4
642tracksRegLiveness: true
643liveins:
644  - { reg: '%rdi' }
645  - { reg: '%rsi' }
646body:             |
647  bb.0.entry:
648    liveins: %rdi, %rsi
649
650    TEST64rr %rdi, %rdi, implicit-def %eflags
651    JE_1 %bb.2.is_null, implicit killed %eflags
652
653  bb.1.not_null:
654    liveins: %rdi, %rsi
655
656    %rcx = MOV64rm killed %rsi, 1, _, 0, _ :: (load 8 from %ir.ptr2)
657    %esi = MOV32ri 3076
658    %eax = BEXTR32rm killed %rdi, 1, _, 0, _, killed %esi, implicit-def dead %eflags :: (load 4 from %ir.ptr)
659    %eax = ADD32rm killed %eax, killed %rcx, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.val)
660    RETQ %eax
661
662  bb.2.is_null:
663    %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags
664    RETQ %eax
665
666...
667---
668name:            use_alternate_load_op
669# CHECK-LABEL: name:            use_alternate_load_op
670# CHECK: bb.0.entry:
671# CHECK: %rax = FAULTING_OP 1, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 0, _
672# CHECK-NEXT: JMP_1 %bb.1.not_null
673# CHECK: bb.1.not_null
674
675alignment:       4
676tracksRegLiveness: true
677liveins:
678  - { reg: '%rdi' }
679  - { reg: '%rsi' }
680body:             |
681  bb.0.entry:
682    liveins: %rdi, %rsi
683
684    TEST64rr %rdi, %rdi, implicit-def %eflags
685    JE_1 %bb.2.is_null, implicit killed %eflags
686
687  bb.1.not_null:
688    liveins: %rdi, %rsi
689
690    %rcx = MOV64rm killed %rsi, 1, _, 0, _
691    %rcx = AND64rm killed %rcx, %rdi, 1, _, 0, _, implicit-def dead %eflags
692    %rax = MOV64rm killed %rdi, 1, _, 0, _
693    RETQ %eax
694
695  bb.2.is_null:
696    %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags
697    RETQ %eax
698
699...
700---
701name:            imp_null_check_gep_load_with_use_dep
702# CHECK-LABEL: name:            imp_null_check_gep_load_with_use_dep
703# CHECK:  bb.0.entry:
704# CHECK:    %eax = FAULTING_OP 1, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 0, _, implicit-def %rax :: (load 4 from %ir.x)
705# CHECK-NEXT:    JMP_1 %bb.1.not_null
706alignment:       4
707tracksRegLiveness: true
708liveins:
709  - { reg: '%rdi' }
710  - { reg: '%rsi' }
711body:             |
712  bb.0.entry:
713    liveins: %rsi, %rdi
714
715    TEST64rr %rdi, %rdi, implicit-def %eflags
716    JE_1 %bb.1.is_null, implicit %eflags
717
718  bb.2.not_null:
719    liveins: %rdi, %rsi
720
721    %rsi = ADD64rr %rsi, %rdi, implicit-def dead %eflags
722    %eax = MOV32rm killed %rdi, 1, _, 0, _, implicit-def %rax :: (load 4 from %ir.x)
723    %eax = LEA64_32r killed %rax, 1, killed %rsi, 4, _
724    RETQ %eax
725
726  bb.1.is_null:
727    %eax = MOV32ri 42
728    RETQ %eax
729
730...
731---
732name:            imp_null_check_load_with_base_sep
733# CHECK-LABEL: name:            imp_null_check_load_with_base_sep
734# CHECK:  bb.0.entry:
735# CHECK:     %rsi = ADD64rr %rsi, %rdi, implicit-def dead %eflags
736# CHECK-NEXT:    %esi = FAULTING_OP 1, %bb.2.is_null, {{[0-9]+}}, %esi, %rdi, 1, _, 0, _, implicit-def %eflags
737# CHECK-NEXT:    JMP_1 %bb.1.not_null
738alignment:       4
739tracksRegLiveness: true
740liveins:
741  - { reg: '%rdi' }
742  - { reg: '%rsi' }
743body:             |
744  bb.0.entry:
745    liveins: %rsi, %rdi
746
747    TEST64rr %rdi, %rdi, implicit-def %eflags
748    JE_1 %bb.1.is_null, implicit %eflags
749
750  bb.2.not_null:
751    liveins: %rdi, %rsi
752
753    %rsi = ADD64rr %rsi, %rdi, implicit-def dead %eflags
754    %esi = AND32rm killed %esi, %rdi, 1, _, 0, _, implicit-def dead %eflags
755    %eax = MOV32rr %esi
756    RETQ %eax
757
758  bb.1.is_null:
759    %eax = MOV32ri 42
760    RETQ %eax
761
762...
763---
764name:            inc_store
765# CHECK-LABEL: name:            inc_store
766# CHECK: bb.0.entry:
767# CHECK:  _ = FAULTING_OP 3, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 0, _, %rsi
768# CHECK-NEXT: JMP_1 %bb.1.not_null
769# CHECK: bb.1.not_null
770
771alignment:       4
772tracksRegLiveness: true
773liveins:
774  - { reg: '%rdi' }
775  - { reg: '%rsi' }
776body:             |
777  bb.0.entry:
778    liveins: %rdi, %rsi
779
780    TEST64rr %rdi, %rdi, implicit-def %eflags
781    JE_1 %bb.2.is_null, implicit killed %eflags
782
783  bb.1.not_null:
784    liveins: %rdi, %rsi
785
786    MOV64mr killed %rdi, 1, _, 0, _, killed %rsi
787    RETQ
788
789  bb.2.is_null:
790    RETQ
791
792...
793---
794name:            inc_store_plus_offset
795# CHECK-LABEL: inc_store_plus_offset
796# CHECK: bb.0.entry:
797# CHECK:  _ = FAULTING_OP 3, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 16, _, %rsi
798# CHECK-NEXT: JMP_1 %bb.1.not_null
799# CHECK: bb.1.not_null
800
801alignment:       4
802tracksRegLiveness: true
803liveins:
804  - { reg: '%rdi' }
805  - { reg: '%rsi' }
806body:             |
807  bb.0.entry:
808    liveins: %rdi, %rsi
809
810    TEST64rr %rdi, %rdi, implicit-def %eflags
811    JE_1 %bb.2.is_null, implicit killed %eflags
812
813  bb.1.not_null:
814    liveins: %rdi, %rsi
815
816    MOV64mr killed %rdi, 1, _, 16, _, killed %rsi
817    RETQ
818
819  bb.2.is_null:
820    RETQ
821
822...
823---
824name:            inc_store_with_dep
825# CHECK-LABEL: inc_store_with_dep
826# CHECK: bb.0.entry:
827# CHECK:  %esi = ADD32rr killed %esi, killed %esi, implicit-def dead %eflags
828# CHECK-NEXT:  _ = FAULTING_OP 3, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 16, _, %esi
829# CHECK-NEXT: JMP_1 %bb.1.not_null
830# CHECK: bb.1.not_null
831
832alignment:       4
833tracksRegLiveness: true
834liveins:
835  - { reg: '%rdi' }
836  - { reg: '%rsi' }
837body:             |
838  bb.0.entry:
839    liveins: %rdi, %rsi
840
841    TEST64rr %rdi, %rdi, implicit-def %eflags
842    JE_1 %bb.2.is_null, implicit killed %eflags
843
844  bb.1.not_null:
845    liveins: %rdi, %rsi
846
847    %esi = ADD32rr killed %esi, killed %esi, implicit-def dead %eflags
848    MOV32mr killed %rdi, 1, _, 16, _, killed %esi
849    RETQ
850
851  bb.2.is_null:
852    RETQ
853
854...
855---
856name:            inc_store_with_dep_in_null
857# CHECK-LABEL: inc_store_with_dep_in_null
858# CHECK: bb.0.entry:
859# CHECK:    TEST64rr %rdi, %rdi, implicit-def %eflags
860# CHECK-NEXT:    JE_1 %bb.2.is_null, implicit killed %eflags
861# CHECK: bb.1.not_null
862
863alignment:       4
864tracksRegLiveness: true
865liveins:
866  - { reg: '%rdi' }
867  - { reg: '%rsi' }
868body:             |
869  bb.0.entry:
870    liveins: %rdi, %rsi
871
872    TEST64rr %rdi, %rdi, implicit-def %eflags
873    JE_1 %bb.2.is_null, implicit killed %eflags
874
875  bb.1.not_null:
876    liveins: %rdi, %rsi
877
878    %esi = ADD32rr %esi, %esi, implicit-def dead %eflags
879    MOV32mr killed %rdi, 1, _, 0, _, %esi
880    %eax = MOV32rr killed %esi
881    RETQ %eax
882
883  bb.2.is_null:
884    liveins: %rsi
885
886    %eax = MOV32rr killed %esi
887    RETQ %eax
888
889...
890---
891name:            inc_store_with_volatile
892# CHECK-LABEL: inc_store_with_volatile
893# CHECK: bb.0.entry:
894# CHECK:    TEST64rr %rdi, %rdi, implicit-def %eflags
895# CHECK-NEXT:    JE_1 %bb.2.is_null, implicit killed %eflags
896# CHECK: bb.1.not_null
897
898alignment:       4
899tracksRegLiveness: true
900liveins:
901  - { reg: '%rdi' }
902  - { reg: '%rsi' }
903body:             |
904  bb.0.entry:
905    liveins: %rdi, %rsi
906
907    TEST64rr %rdi, %rdi, implicit-def %eflags
908    JE_1 %bb.2.is_null, implicit killed %eflags
909
910  bb.1.not_null:
911    liveins: %rdi, %rsi
912
913    MOV32mr killed %rdi, 1, _, 0, _, killed %esi :: (volatile store 4 into %ir.ptr)
914    RETQ
915
916  bb.2.is_null:
917    RETQ
918
919...
920---
921name:            inc_store_with_two_dep
922# CHECK-LABEL: inc_store_with_two_dep
923# CHECK: bb.0.entry:
924# CHECK:    TEST64rr %rdi, %rdi, implicit-def %eflags
925# CHECK-NEXT:    JE_1 %bb.2.is_null, implicit killed %eflags
926# CHECK: bb.1.not_null
927
928alignment:       4
929tracksRegLiveness: true
930liveins:
931  - { reg: '%rdi' }
932  - { reg: '%rsi' }
933body:             |
934  bb.0.entry:
935    liveins: %rdi, %rsi
936
937    TEST64rr %rdi, %rdi, implicit-def %eflags
938    JE_1 %bb.2.is_null, implicit killed %eflags
939
940  bb.1.not_null:
941    liveins: %rdi, %rsi
942
943    %esi = ADD32rr killed %esi, killed %esi, implicit-def dead %eflags
944    %esi = ADD32ri killed %esi, 15, implicit-def dead %eflags
945    MOV32mr killed %rdi, 1, _, 16, _, killed %esi
946    RETQ
947
948  bb.2.is_null:
949    RETQ
950
951...
952---
953name:            inc_store_with_redefined_base
954# CHECK-LABEL: inc_store_with_redefined_base
955# CHECK: bb.0.entry:
956# CHECK:    TEST64rr %rdi, %rdi, implicit-def %eflags
957# CHECK-NEXT:    JE_1 %bb.2.is_null, implicit killed %eflags
958# CHECK: bb.1.not_null
959
960alignment:       4
961tracksRegLiveness: true
962liveins:
963  - { reg: '%rdi' }
964  - { reg: '%rsi' }
965body:             |
966  bb.0.entry:
967    liveins: %rdi, %rsi
968
969    TEST64rr %rdi, %rdi, implicit-def %eflags
970    JE_1 %bb.2.is_null, implicit killed %eflags
971
972  bb.1.not_null:
973    liveins: %rdi, %rsi
974
975    %rdi = ADD64rr killed %rdi, killed %rdi, implicit-def dead %eflags
976    MOV32mr killed %rdi, 1, _, 16, _, killed %esi
977    RETQ
978
979  bb.2.is_null:
980    RETQ
981
982...
983---
984name:            inc_store_with_reused_base
985# CHECK-LABEL: inc_store_with_reused_base
986# CHECK: bb.0.entry:
987# CHECK:  _ = FAULTING_OP 3, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 16, _, %esi
988# CHECK-NEXT: JMP_1 %bb.1.not_null
989# CHECK: bb.1.not_null
990
991alignment:       4
992tracksRegLiveness: true
993liveins:
994  - { reg: '%rdi' }
995  - { reg: '%rsi' }
996body:             |
997  bb.0.entry:
998    liveins: %rdi, %rsi
999
1000    TEST64rr %rdi, %rdi, implicit-def %eflags
1001    JE_1 %bb.2.is_null, implicit killed %eflags
1002
1003  bb.1.not_null:
1004    liveins: %rdi, %rsi
1005
1006    %rax = MOV64rr %rdi
1007    MOV32mr killed %rdi, 1, _, 16, _, killed %esi
1008    RETQ %eax
1009
1010  bb.2.is_null:
1011    %rax = XOR64rr undef %rax, undef %rax, implicit-def dead %eflags
1012    RETQ %eax
1013
1014...
1015---
1016name:            inc_store_across_call
1017# CHECK-LABEL: inc_store_across_call
1018# CHECK: bb.0.entry:
1019# CHECK:    TEST64rr %rbx, %rbx, implicit-def %eflags
1020# CHECK-NEXT:    JE_1 %bb.2.is_null, implicit killed %eflags
1021# CHECK: bb.1.not_null
1022
1023alignment:       4
1024tracksRegLiveness: true
1025liveins:
1026  - { reg: '%rdi' }
1027calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx',
1028                        '%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15',
1029                        '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d',
1030                        '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ]
1031body:             |
1032  bb.0.entry:
1033    liveins: %rdi, %rbx
1034
1035    frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp
1036    CFI_INSTRUCTION def_cfa_offset 16
1037    CFI_INSTRUCTION offset %rbx, -16
1038    %rbx = MOV64rr killed %rdi
1039    TEST64rr %rbx, %rbx, implicit-def %eflags
1040    JE_1 %bb.2.is_null, implicit killed %eflags
1041
1042  bb.1.not_null:
1043    liveins: %rbx
1044
1045    CALL64pcrel32 @f, csr_64, implicit %rsp, implicit-def %rsp
1046    MOV32mi %rbx, 1, _, 0, _, 20
1047    %rax = MOV64rr killed %rbx
1048    %rbx = POP64r implicit-def %rsp, implicit %rsp
1049    RETQ %eax
1050
1051  bb.2.is_null:
1052    %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags
1053    %rbx = POP64r implicit-def %rsp, implicit %rsp
1054    RETQ %eax
1055
1056...
1057---
1058name:            inc_store_with_dep_in_dep
1059# CHECK-LABEL: inc_store_with_dep_in_dep
1060# CHECK: bb.0.entry:
1061# CHECK:    TEST64rr %rdi, %rdi, implicit-def %eflags
1062# CHECK-NEXT:    JE_1 %bb.2.is_null, implicit killed %eflags
1063# CHECK: bb.1.not_null
1064
1065alignment:       4
1066tracksRegLiveness: true
1067liveins:
1068  - { reg: '%rdi' }
1069  - { reg: '%rsi' }
1070body:             |
1071  bb.0.entry:
1072    liveins: %rdi, %rsi
1073
1074    TEST64rr %rdi, %rdi, implicit-def %eflags
1075    JE_1 %bb.2.is_null, implicit killed %eflags
1076
1077  bb.1.not_null:
1078    liveins: %rdi, %rsi
1079
1080    %eax = MOV32rr %esi
1081    %esi = ADD32ri killed %esi, 15, implicit-def dead %eflags
1082    MOV32mr killed %rdi, 1, _, 0, _, killed %esi
1083    RETQ %eax
1084
1085  bb.2.is_null:
1086    %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags
1087    RETQ %eax
1088
1089...
1090---
1091name:            inc_store_with_load_over_store
1092# CHECK-LABEL: inc_store_with_load_over_store
1093# CHECK: bb.0.entry:
1094# CHECK:    TEST64rr %rdi, %rdi, implicit-def %eflags
1095# CHECK-NEXT:    JE_1 %bb.2.is_null, implicit killed %eflags
1096# CHECK: bb.1.not_null
1097
1098alignment:       4
1099tracksRegLiveness: true
1100liveins:
1101  - { reg: '%rdi' }
1102  - { reg: '%rsi' }
1103body:             |
1104  bb.0.entry:
1105    liveins: %rdi, %rsi
1106
1107    TEST64rr %rdi, %rdi, implicit-def %eflags
1108    JE_1 %bb.2.is_null, implicit killed %eflags
1109
1110  bb.1.not_null:
1111    liveins: %rdi, %rsi
1112
1113    MOV32mi killed %rsi, 1, _, 0, _, 2
1114    %eax = MOV32rm killed %rdi, 1, _, 0, _
1115    RETQ %eax
1116
1117  bb.2.is_null:
1118    %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags
1119    RETQ %eax
1120
1121...
1122---
1123name:            inc_store_with_store_over_load
1124# CHECK-LABEL: inc_store_with_store_over_load
1125# CHECK: bb.0.entry:
1126# CHECK:    TEST64rr %rdi, %rdi, implicit-def %eflags
1127# CHECK-NEXT:    JE_1 %bb.2.is_null, implicit killed %eflags
1128# CHECK: bb.1.not_null
1129
1130alignment:       4
1131tracksRegLiveness: true
1132liveins:
1133  - { reg: '%rdi' }
1134  - { reg: '%rsi' }
1135body:             |
1136  bb.0.entry:
1137    liveins: %rdi, %rsi
1138
1139    TEST64rr %rdi, %rdi, implicit-def %eflags
1140    JE_1 %bb.2.is_null, implicit killed %eflags
1141
1142  bb.1.not_null:
1143    liveins: %rdi, %rsi
1144
1145    %eax = MOV32rm killed %rsi, 1, _, 0, _
1146    MOV32mi killed %rdi, 1, _, 0, _, 2
1147    RETQ %eax
1148
1149  bb.2.is_null:
1150    %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags
1151    RETQ %eax
1152
1153...
1154---
1155name:            inc_store_with_store_over_store
1156# CHECK-LABEL: inc_store_with_store_over_store
1157# CHECK: bb.0.entry:
1158# CHECK:    TEST64rr %rdi, %rdi, implicit-def %eflags
1159# CHECK-NEXT:    JE_1 %bb.2.is_null, implicit killed %eflags
1160# CHECK: bb.1.not_null
1161
1162alignment:       4
1163tracksRegLiveness: true
1164liveins:
1165  - { reg: '%rdi' }
1166  - { reg: '%rsi' }
1167body:             |
1168  bb.0.entry:
1169    liveins: %rdi, %rsi
1170
1171    TEST64rr %rdi, %rdi, implicit-def %eflags
1172    JE_1 %bb.2.is_null, implicit killed %eflags
1173
1174  bb.1.not_null:
1175    liveins: %rdi, %rsi
1176
1177    MOV32mi killed %rsi, 1, _, 0, _, 3
1178    MOV32mi killed %rdi, 1, _, 0, _, 2
1179    RETQ
1180
1181  bb.2.is_null:
1182    RETQ
1183
1184...
1185---
1186name:            inc_store_with_load_and_store
1187# CHECK-LABEL: inc_store_with_load_and_store
1188# CHECK: bb.0.entry:
1189# CHECK:  _ = FAULTING_OP 2, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 0, _, %esi, implicit-def %eflags
1190# CHECK-NEXT: JMP_1 %bb.1.not_null
1191# CHECK: bb.1.not_null
1192
1193alignment:       4
1194tracksRegLiveness: true
1195liveins:
1196  - { reg: '%rdi' }
1197  - { reg: '%rsi' }
1198body:             |
1199  bb.0.entry:
1200    liveins: %rdi, %rsi
1201
1202    TEST64rr %rdi, %rdi, implicit-def %eflags
1203    JE_1 %bb.2.is_null, implicit killed %eflags
1204
1205  bb.1.not_null:
1206    liveins: %rdi, %rsi
1207
1208    %esi = ADD32rr %esi, %esi, implicit-def dead %eflags
1209    ADD32mr killed %rdi, 1, _, 0, _, killed %esi, implicit-def dead %eflags
1210    RETQ
1211
1212  bb.2.is_null:
1213    RETQ
1214
1215...
1216---
1217name:            inc_store_and_load_no_alias
1218# CHECK-LABEL: inc_store_and_load_no_alias
1219# CHECK: bb.0.entry:
1220# CHECK:  %eax = FAULTING_OP 1, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 0, _ :: (load 4 from %ir.ptr)
1221# CHECK-NEXT: JMP_1 %bb.1.not_null
1222# CHECK: bb.1.not_null
1223
1224alignment:       4
1225tracksRegLiveness: true
1226liveins:
1227  - { reg: '%rdi' }
1228  - { reg: '%rsi' }
1229body:             |
1230  bb.0.entry:
1231    liveins: %rdi, %rsi
1232
1233    TEST64rr %rdi, %rdi, implicit-def %eflags
1234    JE_1 %bb.2.is_null, implicit killed %eflags
1235
1236  bb.1.not_null:
1237    liveins: %rdi, %rsi
1238
1239    MOV32mi killed %rsi, 1, _, 0, _, 3 :: (store 4 into %ir.ptr2)
1240    %eax = MOV32rm killed %rdi, 1, _, 0, _ :: (load 4 from %ir.ptr)
1241    RETQ %eax
1242
1243  bb.2.is_null:
1244    %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags
1245    RETQ %eax
1246
1247...
1248---
1249name:            inc_store_and_load_alias
1250# CHECK-LABEL: inc_store_and_load_alias
1251# CHECK: bb.0.entry:
1252# CHECK:    TEST64rr %rdi, %rdi, implicit-def %eflags
1253# CHECK-NEXT:    JE_1 %bb.2.is_null, implicit killed %eflags
1254# CHECK: bb.1.not_null
1255
1256alignment:       4
1257tracksRegLiveness: true
1258liveins:
1259  - { reg: '%rdi' }
1260  - { reg: '%rsi' }
1261body:             |
1262  bb.0.entry:
1263    liveins: %rdi, %rsi
1264
1265    TEST64rr %rdi, %rdi, implicit-def %eflags
1266    JE_1 %bb.2.is_null, implicit killed %eflags
1267
1268  bb.1.not_null:
1269    liveins: %rdi, %rsi
1270
1271    MOV32mi killed %rsi, 1, _, 0, _, 3 :: (store 4 into %ir.ptr2)
1272    %eax = MOV32rm killed %rdi, 1, _, 0, _ :: (load 4 from %ir.ptr)
1273    RETQ %eax
1274
1275  bb.2.is_null:
1276    %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags
1277    RETQ %eax
1278
1279...
1280---
1281name:            inc_spill_dep
1282# CHECK-LABEL: inc_spill_dep
1283# CHECK: bb.0.entry:
1284# CHECK:    TEST64rr %rdi, %rdi, implicit-def %eflags
1285# CHECK-NEXT:    JE_1 %bb.2.is_null, implicit killed %eflags
1286# CHECK: bb.1.not_null
1287
1288alignment:       4
1289tracksRegLiveness: true
1290stack:
1291  - { id: 0, type: spill-slot, offset: -8, size: 8, alignment: 8}
1292liveins:
1293  - { reg: '%rdi' }
1294  - { reg: '%rsi' }
1295body:             |
1296  bb.0.entry:
1297    liveins: %rdi, %rsi
1298
1299    %rsp = frame-setup SUB64ri8 %rsp, 8, implicit-def dead %eflags
1300    MOV32mr %rsp, 1, %noreg, 0, %noreg, %esi :: (store 4 into %stack.0)
1301    TEST64rr %rdi, %rdi, implicit-def %eflags
1302    JE_1 %bb.2.is_null, implicit killed %eflags
1303
1304  bb.1.not_null:
1305    liveins: %rdi, %rsi
1306
1307    %r14d = MOV32rm %rsp, 1, %noreg, 0, %noreg :: (load 4 from %stack.0)
1308    MOV64mr %rsp, 1, %noreg, 0, %noreg, %rdi :: (store 8 into %stack.0)
1309    %edi = MOV32rm %rdi, 1, %noreg, 8, %noreg :: (load 4 from %ir.ptr)
1310    %eax = MOV32rr %edi
1311    RETQ %eax
1312
1313  bb.2.is_null:
1314    %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags
1315    RETQ %eax
1316
1317...
1318