[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / X86 / implicit-null-check.ll
blobb02f66fe8cfb1ca791293c2bdf89ab2f8494535c
1 ; RUN: llc -verify-machineinstrs -O3 -mtriple=x86_64-apple-macosx -enable-implicit-null-checks < %s | FileCheck %s
3 define i32 @imp_null_check_load(ptr %x) {
4 ; CHECK-LABEL: imp_null_check_load:
5 ; CHECK:       ## %bb.0: ## %entry
6 ; CHECK-NEXT:  Ltmp0:
7 ; CHECK-NEXT:    movl (%rdi), %eax ## on-fault: LBB0_1
8 ; CHECK-NEXT:  ## %bb.2: ## %not_null
9 ; CHECK-NEXT:    retq
10 ; CHECK-NEXT:  LBB0_1: ## %is_null
11 ; CHECK-NEXT:    movl $42, %eax
12 ; CHECK-NEXT:    retq
14  entry:
15   %c = icmp eq ptr %x, null
16   br i1 %c, label %is_null, label %not_null, !make.implicit !0
18  is_null:
19   ret i32 42
21  not_null:
22   %t = load i32, ptr %x
23   ret i32 %t
26 ; TODO: can make implicit
27 define i32 @imp_null_check_unordered_load(ptr %x) {
28 ; CHECK-LABEL: imp_null_check_unordered_load:
29 ; CHECK:       ## %bb.0: ## %entry
30 ; CHECK-NEXT:  Ltmp1:
31 ; CHECK-NEXT:    movl (%rdi), %eax ## on-fault: LBB1_1
32 ; CHECK-NEXT:  ## %bb.2: ## %not_null
33 ; CHECK-NEXT:    retq
34 ; CHECK-NEXT:  LBB1_1: ## %is_null
35 ; CHECK-NEXT:    movl $42, %eax
36 ; CHECK-NEXT:    retq
38  entry:
39   %c = icmp eq ptr %x, null
40   br i1 %c, label %is_null, label %not_null, !make.implicit !0
42  is_null:
43   ret i32 42
45  not_null:
46   %t = load atomic i32, ptr %x unordered, align 4
47   ret i32 %t
51 ; TODO: Can be converted into implicit check.
52 ;; Probably could be implicit, but we're conservative for now
53 define i32 @imp_null_check_seq_cst_load(ptr %x) {
54 ; CHECK-LABEL: imp_null_check_seq_cst_load:
55 ; CHECK:       ## %bb.0: ## %entry
56 ; CHECK-NEXT:    testq %rdi, %rdi
57 ; CHECK-NEXT:    je LBB2_1
58 ; CHECK-NEXT:  ## %bb.2: ## %not_null
59 ; CHECK-NEXT:    movl (%rdi), %eax
60 ; CHECK-NEXT:    retq
61 ; CHECK-NEXT:  LBB2_1: ## %is_null
62 ; CHECK-NEXT:    movl $42, %eax
63 ; CHECK-NEXT:    retq
65  entry:
66   %c = icmp eq ptr %x, null
67   br i1 %c, label %is_null, label %not_null, !make.implicit !0
69  is_null:
70   ret i32 42
72  not_null:
73   %t = load atomic i32, ptr %x seq_cst, align 4
74   ret i32 %t
77 ;; Might be memory mapped IO, so can't rely on fault behavior
78 define i32 @imp_null_check_volatile_load(ptr %x) {
79 ; CHECK-LABEL: imp_null_check_volatile_load:
80 ; CHECK:       ## %bb.0: ## %entry
81 ; CHECK-NEXT:    testq %rdi, %rdi
82 ; CHECK-NEXT:    je LBB3_1
83 ; CHECK-NEXT:  ## %bb.2: ## %not_null
84 ; CHECK-NEXT:    movl (%rdi), %eax
85 ; CHECK-NEXT:    retq
86 ; CHECK-NEXT:  LBB3_1: ## %is_null
87 ; CHECK-NEXT:    movl $42, %eax
88 ; CHECK-NEXT:    retq
90  entry:
91   %c = icmp eq ptr %x, null
92   br i1 %c, label %is_null, label %not_null, !make.implicit !0
94  is_null:
95   ret i32 42
97  not_null:
98   %t = load volatile i32, ptr %x, align 4
99   ret i32 %t
103 define i8 @imp_null_check_load_i8(ptr %x) {
104 ; CHECK-LABEL: imp_null_check_load_i8:
105 ; CHECK:       ## %bb.0: ## %entry
106 ; CHECK-NEXT:  Ltmp2:
107 ; CHECK-NEXT:    movb (%rdi), %al ## on-fault: LBB4_1
108 ; CHECK-NEXT:  ## %bb.2: ## %not_null
109 ; CHECK-NEXT:    retq
110 ; CHECK-NEXT:  LBB4_1: ## %is_null
111 ; CHECK-NEXT:    movb $42, %al
112 ; CHECK-NEXT:    retq
114  entry:
115   %c = icmp eq ptr %x, null
116   br i1 %c, label %is_null, label %not_null, !make.implicit !0
118  is_null:
119   ret i8 42
121  not_null:
122   %t = load i8, ptr %x
123   ret i8 %t
126 define i256 @imp_null_check_load_i256(ptr %x) {
127 ; CHECK-LABEL: imp_null_check_load_i256:
128 ; CHECK:       ## %bb.0: ## %entry
129 ; CHECK-NEXT:    movq %rdi, %rax
130 ; CHECK-NEXT:  Ltmp3:
131 ; CHECK-NEXT:    movq (%rsi), %rcx ## on-fault: LBB5_1
132 ; CHECK-NEXT:  ## %bb.2: ## %not_null
133 ; CHECK-NEXT:    movq 8(%rsi), %rdx
134 ; CHECK-NEXT:    movq 16(%rsi), %rdi
135 ; CHECK-NEXT:    movq 24(%rsi), %rsi
136 ; CHECK-NEXT:    movq %rsi, 24(%rax)
137 ; CHECK-NEXT:    movq %rdi, 16(%rax)
138 ; CHECK-NEXT:    movq %rdx, 8(%rax)
139 ; CHECK-NEXT:    movq %rcx, (%rax)
140 ; CHECK-NEXT:    retq
141 ; CHECK-NEXT:  LBB5_1: ## %is_null
142 ; CHECK-NEXT:    movq $0, 24(%rax)
143 ; CHECK-NEXT:    movq $0, 16(%rax)
144 ; CHECK-NEXT:    movq $0, 8(%rax)
145 ; CHECK-NEXT:    movq $42, (%rax)
146 ; CHECK-NEXT:    retq
148  entry:
149   %c = icmp eq ptr %x, null
150   br i1 %c, label %is_null, label %not_null, !make.implicit !0
152  is_null:
153   ret i256 42
155  not_null:
156   %t = load i256, ptr %x
157   ret i256 %t
162 define i32 @imp_null_check_gep_load(ptr %x) {
163 ; CHECK-LABEL: imp_null_check_gep_load:
164 ; CHECK:       ## %bb.0: ## %entry
165 ; CHECK-NEXT:  Ltmp4:
166 ; CHECK-NEXT:    movl 128(%rdi), %eax ## on-fault: LBB6_1
167 ; CHECK-NEXT:  ## %bb.2: ## %not_null
168 ; CHECK-NEXT:    retq
169 ; CHECK-NEXT:  LBB6_1: ## %is_null
170 ; CHECK-NEXT:    movl $42, %eax
171 ; CHECK-NEXT:    retq
173  entry:
174   %c = icmp eq ptr %x, null
175   br i1 %c, label %is_null, label %not_null, !make.implicit !0
177  is_null:
178   ret i32 42
180  not_null:
181   %x.gep = getelementptr i32, ptr %x, i32 32
182   %t = load i32, ptr %x.gep
183   ret i32 %t
186 define i32 @imp_null_check_add_result(ptr %x, i32 %p) {
187 ; CHECK-LABEL: imp_null_check_add_result:
188 ; CHECK:       ## %bb.0: ## %entry
189 ; CHECK-NEXT:  Ltmp5:
190 ; CHECK-NEXT:    addl (%rdi), %esi ## on-fault: LBB7_1
191 ; CHECK-NEXT:  ## %bb.2: ## %not_null
192 ; CHECK-NEXT:    movl %esi, %eax
193 ; CHECK-NEXT:    retq
194 ; CHECK-NEXT:  LBB7_1: ## %is_null
195 ; CHECK-NEXT:    movl $42, %eax
196 ; CHECK-NEXT:    retq
198  entry:
199   %c = icmp eq ptr %x, null
200   br i1 %c, label %is_null, label %not_null, !make.implicit !0
202  is_null:
203   ret i32 42
205  not_null:
206   %t = load i32, ptr %x
207   %p1 = add i32 %t, %p
208   ret i32 %p1
211 define i32 @imp_null_check_sub_result(ptr %x, i32 %p) {
212 ; CHECK-LABEL: imp_null_check_sub_result:
213 ; CHECK:       ## %bb.0: ## %entry
214 ; CHECK-NEXT:  Ltmp6:
215 ; CHECK-NEXT:    movl (%rdi), %eax ## on-fault: LBB8_1
216 ; CHECK-NEXT:  ## %bb.2: ## %not_null
217 ; CHECK-NEXT:    subl %esi, %eax
218 ; CHECK-NEXT:    retq
219 ; CHECK-NEXT:  LBB8_1: ## %is_null
220 ; CHECK-NEXT:    movl $42, %eax
221 ; CHECK-NEXT:    retq
223  entry:
224   %c = icmp eq ptr %x, null
225   br i1 %c, label %is_null, label %not_null, !make.implicit !0
227  is_null:
228   ret i32 42
230  not_null:
231   %t = load i32, ptr %x
232   %p1 = sub i32 %t, %p
233   ret i32 %p1
236 define i32 @imp_null_check_mul_result(ptr %x, i32 %p) {
237 ; CHECK-LABEL: imp_null_check_mul_result:
238 ; CHECK:       ## %bb.0: ## %entry
239 ; CHECK-NEXT:  Ltmp7:
240 ; CHECK-NEXT:    imull (%rdi), %esi ## on-fault: LBB9_1
241 ; CHECK-NEXT:  ## %bb.2: ## %not_null
242 ; CHECK-NEXT:    movl %esi, %eax
243 ; CHECK-NEXT:    retq
244 ; CHECK-NEXT:  LBB9_1: ## %is_null
245 ; CHECK-NEXT:    movl $42, %eax
246 ; CHECK-NEXT:    retq
248  entry:
249   %c = icmp eq ptr %x, null
250   br i1 %c, label %is_null, label %not_null, !make.implicit !0
252  is_null:
253   ret i32 42
255  not_null:
256   %t = load i32, ptr %x
257   %p1 = mul i32 %t, %p
258   ret i32 %p1
261 define i32 @imp_null_check_udiv_result(ptr %x, i32 %p) {
262 ; CHECK-LABEL: imp_null_check_udiv_result:
263 ; CHECK:       ## %bb.0: ## %entry
264 ; CHECK-NEXT:  Ltmp8:
265 ; CHECK-NEXT:    movl (%rdi), %eax ## on-fault: LBB10_1
266 ; CHECK-NEXT:  ## %bb.2: ## %not_null
267 ; CHECK-NEXT:    xorl %edx, %edx
268 ; CHECK-NEXT:    divl %esi
269 ; CHECK-NEXT:    retq
270 ; CHECK-NEXT:  LBB10_1: ## %is_null
271 ; CHECK-NEXT:    movl $42, %eax
272 ; CHECK-NEXT:    retq
274  entry:
275   %c = icmp eq ptr %x, null
276   br i1 %c, label %is_null, label %not_null, !make.implicit !0
278  is_null:
279   ret i32 42
281  not_null:
282   %t = load i32, ptr %x
283   %p1 = udiv i32 %t, %p
284   ret i32 %p1
287 define i32 @imp_null_check_shl_result(ptr %x, i32 %p) {
288 ; CHECK-LABEL: imp_null_check_shl_result:
289 ; CHECK:       ## %bb.0: ## %entry
290 ; CHECK-NEXT:  Ltmp9:
291 ; CHECK-NEXT:    movl (%rdi), %eax ## on-fault: LBB11_1
292 ; CHECK-NEXT:  ## %bb.2: ## %not_null
293 ; CHECK-NEXT:    movl %esi, %ecx
294 ; CHECK-NEXT:    shll %cl, %eax
295 ; CHECK-NEXT:    retq
296 ; CHECK-NEXT:  LBB11_1: ## %is_null
297 ; CHECK-NEXT:    movl $42, %eax
298 ; CHECK-NEXT:    retq
300  entry:
301   %c = icmp eq ptr %x, null
302   br i1 %c, label %is_null, label %not_null, !make.implicit !0
304  is_null:
305   ret i32 42
307  not_null:
308   %t = load i32, ptr %x
309   %p1 = shl i32 %t, %p
310   ret i32 %p1
313 define i32 @imp_null_check_lshr_result(ptr %x, i32 %p) {
314 ; CHECK-LABEL: imp_null_check_lshr_result:
315 ; CHECK:       ## %bb.0: ## %entry
316 ; CHECK-NEXT:  Ltmp10:
317 ; CHECK-NEXT:    movl (%rdi), %eax ## on-fault: LBB12_1
318 ; CHECK-NEXT:  ## %bb.2: ## %not_null
319 ; CHECK-NEXT:    movl %esi, %ecx
320 ; CHECK-NEXT:    shrl %cl, %eax
321 ; CHECK-NEXT:    retq
322 ; CHECK-NEXT:  LBB12_1: ## %is_null
323 ; CHECK-NEXT:    movl $42, %eax
324 ; CHECK-NEXT:    retq
326  entry:
327   %c = icmp eq ptr %x, null
328   br i1 %c, label %is_null, label %not_null, !make.implicit !0
330  is_null:
331   ret i32 42
333  not_null:
334   %t = load i32, ptr %x
335   %p1 = lshr i32 %t, %p
336   ret i32 %p1
342 define i32 @imp_null_check_hoist_over_unrelated_load(ptr %x, ptr %y, ptr %z) {
343 ; CHECK-LABEL: imp_null_check_hoist_over_unrelated_load:
344 ; CHECK:       ## %bb.0: ## %entry
345 ; CHECK-NEXT:  Ltmp11:
346 ; CHECK-NEXT:    movl (%rdi), %eax ## on-fault: LBB13_1
347 ; CHECK-NEXT:  ## %bb.2: ## %not_null
348 ; CHECK-NEXT:    movl (%rsi), %ecx
349 ; CHECK-NEXT:    movl %ecx, (%rdx)
350 ; CHECK-NEXT:    retq
351 ; CHECK-NEXT:  LBB13_1: ## %is_null
352 ; CHECK-NEXT:    movl $42, %eax
353 ; CHECK-NEXT:    retq
355  entry:
356   %c = icmp eq ptr %x, null
357   br i1 %c, label %is_null, label %not_null, !make.implicit !0
359  is_null:
360   ret i32 42
362  not_null:
363   %t0 = load i32, ptr %y
364   %t1 = load i32, ptr %x
365   store i32 %t0, ptr %z
366   ret i32 %t1
369 define i32 @imp_null_check_via_mem_comparision(ptr %x, i32 %val) {
370 ; CHECK-LABEL: imp_null_check_via_mem_comparision:
371 ; CHECK:       ## %bb.0: ## %entry
372 ; CHECK-NEXT:  Ltmp12:
373 ; CHECK-NEXT:    cmpl %esi, 4(%rdi) ## on-fault: LBB14_3
374 ; CHECK-NEXT:  ## %bb.1: ## %not_null
375 ; CHECK-NEXT:    jge LBB14_2
376 ; CHECK-NEXT:  ## %bb.4: ## %ret_100
377 ; CHECK-NEXT:    movl $100, %eax
378 ; CHECK-NEXT:    retq
379 ; CHECK-NEXT:  LBB14_3: ## %is_null
380 ; CHECK-NEXT:    movl $42, %eax
381 ; CHECK-NEXT:    retq
382 ; CHECK-NEXT:  LBB14_2: ## %ret_200
383 ; CHECK-NEXT:    movl $200, %eax
384 ; CHECK-NEXT:    retq
386  entry:
387   %c = icmp eq ptr %x, null
388   br i1 %c, label %is_null, label %not_null, !make.implicit !0
390  is_null:
391   ret i32 42
393  not_null:
394   %x.loc = getelementptr i32, ptr %x, i32 1
395   %t = load i32, ptr %x.loc
396   %m = icmp slt i32 %t, %val
397   br i1 %m, label %ret_100, label %ret_200
399  ret_100:
400   ret i32 100
402  ret_200:
403   ret i32 200
406 define i32 @imp_null_check_gep_load_with_use_dep(ptr %x, i32 %a) {
407 ; CHECK-LABEL: imp_null_check_gep_load_with_use_dep:
408 ; CHECK:       ## %bb.0: ## %entry
409 ; CHECK-NEXT:    ## kill: def $esi killed $esi def $rsi
410 ; CHECK-NEXT:  Ltmp13:
411 ; CHECK-NEXT:    movl (%rdi), %eax ## on-fault: LBB15_1
412 ; CHECK-NEXT:  ## %bb.2: ## %not_null
413 ; CHECK-NEXT:    addl %edi, %esi
414 ; CHECK-NEXT:    leal 4(%rax,%rsi), %eax
415 ; CHECK-NEXT:    retq
416 ; CHECK-NEXT:  LBB15_1: ## %is_null
417 ; CHECK-NEXT:    movl $42, %eax
418 ; CHECK-NEXT:    retq
420  entry:
421   %c = icmp eq ptr %x, null
422   br i1 %c, label %is_null, label %not_null, !make.implicit !0
424  is_null:
425   ret i32 42
427  not_null:
428   %x.loc = getelementptr i32, ptr %x, i32 1
429   %y = ptrtoint ptr %x.loc to i32
430   %b = add i32 %a, %y
431   %t = load i32, ptr %x
432   %z = add i32 %t, %b
433   ret i32 %z
436 ;; TODO: We could handle this case as we can lift the fence into the
437 ;; previous block before the conditional without changing behavior.
438 define i32 @imp_null_check_load_fence1(ptr %x) {
439 ; CHECK-LABEL: imp_null_check_load_fence1:
440 ; CHECK:       ## %bb.0: ## %entry
441 ; CHECK-NEXT:    testq %rdi, %rdi
442 ; CHECK-NEXT:    je LBB16_1
443 ; CHECK-NEXT:  ## %bb.2: ## %not_null
444 ; CHECK-NEXT:    ##MEMBARRIER
445 ; CHECK-NEXT:    movl (%rdi), %eax
446 ; CHECK-NEXT:    retq
447 ; CHECK-NEXT:  LBB16_1: ## %is_null
448 ; CHECK-NEXT:    movl $42, %eax
449 ; CHECK-NEXT:    retq
451 entry:
452   %c = icmp eq ptr %x, null
453   br i1 %c, label %is_null, label %not_null, !make.implicit !0
455 is_null:
456   ret i32 42
458 not_null:
459   fence acquire
460   %t = load i32, ptr %x
461   ret i32 %t
464 ;; TODO: We could handle this case as we can lift the fence into the
465 ;; previous block before the conditional without changing behavior.
466 define i32 @imp_null_check_load_fence2(ptr %x) {
467 ; CHECK-LABEL: imp_null_check_load_fence2:
468 ; CHECK:       ## %bb.0: ## %entry
469 ; CHECK-NEXT:    testq %rdi, %rdi
470 ; CHECK-NEXT:    je LBB17_1
471 ; CHECK-NEXT:  ## %bb.2: ## %not_null
472 ; CHECK-NEXT:    mfence
473 ; CHECK-NEXT:    movl (%rdi), %eax
474 ; CHECK-NEXT:    retq
475 ; CHECK-NEXT:  LBB17_1: ## %is_null
476 ; CHECK-NEXT:    movl $42, %eax
477 ; CHECK-NEXT:    retq
479 entry:
480   %c = icmp eq ptr %x, null
481   br i1 %c, label %is_null, label %not_null, !make.implicit !0
483 is_null:
484   ret i32 42
486 not_null:
487   fence seq_cst
488   %t = load i32, ptr %x
489   ret i32 %t
492 define void @imp_null_check_store(ptr %x) {
493 ; CHECK-LABEL: imp_null_check_store:
494 ; CHECK:       ## %bb.0: ## %entry
495 ; CHECK-NEXT:  Ltmp14:
496 ; CHECK-NEXT:    movl $1, (%rdi) ## on-fault: LBB18_1
497 ; CHECK-NEXT:  ## %bb.2: ## %not_null
498 ; CHECK-NEXT:    retq
499 ; CHECK-NEXT:  LBB18_1: ## %is_null
500 ; CHECK-NEXT:    retq
502  entry:
503   %c = icmp eq ptr %x, null
504   br i1 %c, label %is_null, label %not_null, !make.implicit !0
506  is_null:
507   ret void
509  not_null:
510   store i32 1, ptr %x
511   ret void
514 ;; TODO: can be implicit
515 define void @imp_null_check_unordered_store(ptr %x) {
516 ; CHECK-LABEL: imp_null_check_unordered_store:
517 ; CHECK:       ## %bb.0: ## %entry
518 ; CHECK-NEXT:  Ltmp15:
519 ; CHECK-NEXT:    movl $1, (%rdi) ## on-fault: LBB19_1
520 ; CHECK-NEXT:  ## %bb.2: ## %not_null
521 ; CHECK-NEXT:    retq
522 ; CHECK-NEXT:  LBB19_1: ## %is_null
523 ; CHECK-NEXT:    retq
525  entry:
526   %c = icmp eq ptr %x, null
527   br i1 %c, label %is_null, label %not_null, !make.implicit !0
529  is_null:
530   ret void
532  not_null:
533   store atomic i32 1, ptr %x unordered, align 4
534   ret void
537 define i32 @imp_null_check_neg_gep_load(ptr %x) {
538 ; CHECK-LABEL: imp_null_check_neg_gep_load:
539 ; CHECK:       ## %bb.0: ## %entry
540 ; CHECK-NEXT:  Ltmp16:
541 ; CHECK-NEXT:    movl -128(%rdi), %eax ## on-fault: LBB20_1
542 ; CHECK-NEXT:  ## %bb.2: ## %not_null
543 ; CHECK-NEXT:    retq
544 ; CHECK-NEXT:  LBB20_1: ## %is_null
545 ; CHECK-NEXT:    movl $42, %eax
546 ; CHECK-NEXT:    retq
548  entry:
549   %c = icmp eq ptr %x, null
550   br i1 %c, label %is_null, label %not_null, !make.implicit !0
552  is_null:
553   ret i32 42
555  not_null:
556   %x.gep = getelementptr i32, ptr %x, i32 -32
557   %t = load i32, ptr %x.gep
558   ret i32 %t
561 ; This redefines the null check reg by doing a zero-extend and a shift on
562 ; itself.
563 ; Converted into implicit null check since both of these operations do not
564 ; change the nullness of %x (i.e. if it is null, it remains null).
565 define i64 @imp_null_check_load_shift_addr(ptr %x) {
566 ; CHECK-LABEL: imp_null_check_load_shift_addr:
567 ; CHECK:       ## %bb.0: ## %entry
568 ; CHECK-NEXT:    shlq $6, %rdi
569 ; CHECK-NEXT:  Ltmp17:
570 ; CHECK-NEXT:    movq 8(%rdi), %rax ## on-fault: LBB21_1
571 ; CHECK-NEXT:  ## %bb.2: ## %not_null
572 ; CHECK-NEXT:    retq
573 ; CHECK-NEXT:  LBB21_1: ## %is_null
574 ; CHECK-NEXT:    movl $42, %eax
575 ; CHECK-NEXT:    retq
577   entry:
578    %c = icmp eq ptr %x, null
579    br i1 %c, label %is_null, label %not_null, !make.implicit !0
581   is_null:
582    ret i64 42
584   not_null:
585    %y = ptrtoint ptr %x to i64
586    %shry = shl i64 %y, 6
587    %y.ptr = inttoptr i64 %shry to ptr
588    %x.loc = getelementptr i64, ptr %y.ptr, i64 1
589    %t = load i64, ptr %x.loc
590    ret i64 %t
593 ; Same as imp_null_check_load_shift_addr but shift is by 3 and this is now
594 ; converted into complex addressing.
595 define i64 @imp_null_check_load_shift_by_3_addr(ptr %x) {
596 ; CHECK-LABEL: imp_null_check_load_shift_by_3_addr:
597 ; CHECK:       ## %bb.0: ## %entry
598 ; CHECK-NEXT:  Ltmp18:
599 ; CHECK-NEXT:    movq 8(,%rdi,8), %rax ## on-fault: LBB22_1
600 ; CHECK-NEXT:  ## %bb.2: ## %not_null
601 ; CHECK-NEXT:    retq
602 ; CHECK-NEXT:  LBB22_1: ## %is_null
603 ; CHECK-NEXT:    movl $42, %eax
604 ; CHECK-NEXT:    retq
606   entry:
607    %c = icmp eq ptr %x, null
608    br i1 %c, label %is_null, label %not_null, !make.implicit !0
610   is_null:
611    ret i64 42
613   not_null:
614    %y = ptrtoint ptr %x to i64
615    %shry = shl i64 %y, 3
616    %y.ptr = inttoptr i64 %shry to ptr
617    %x.loc = getelementptr i64, ptr %y.ptr, i64 1
618    %t = load i64, ptr %x.loc
619    ret i64 %t
622 define i64 @imp_null_check_load_shift_add_addr(ptr %x) {
623 ; CHECK-LABEL: imp_null_check_load_shift_add_addr:
624 ; CHECK:       ## %bb.0: ## %entry
625 ; CHECK:         movq 3526(,%rdi,8), %rax ## on-fault: LBB23_1
626 ; CHECK-NEXT:  ## %bb.2: ## %not_null
627 ; CHECK-NEXT:    retq
628 ; CHECK-NEXT:  LBB23_1: ## %is_null
629 ; CHECK-NEXT:    movl $42, %eax
630 ; CHECK-NEXT:    retq
632   entry:
633    %c = icmp eq ptr %x, null
634    br i1 %c, label %is_null, label %not_null, !make.implicit !0
636   is_null:
637    ret i64 42
639   not_null:
640    %y = ptrtoint ptr %x to i64
641    %shry = shl i64 %y, 3
642    %shry.add = add i64 %shry, 3518
643    %y.ptr = inttoptr i64 %shry.add to ptr
644    %x.loc = getelementptr i64, ptr %y.ptr, i64 1
645    %t = load i64, ptr %x.loc
646    ret i64 %t
648 !0 = !{}