]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGen/X86/implicit-null-checks.mir
Vendor import of llvm release_40 branch r292009:
[FreeBSD/FreeBSD.git] / test / CodeGen / X86 / implicit-null-checks.mir
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   attributes #0 = { "target-features"="+bmi,+bmi2" }
135
136   !0 = !{}
137 ...
138 ---
139 name:            imp_null_check_with_bitwise_op_0
140 # CHECK-LABEL: name:            imp_null_check_with_bitwise_op_0
141 alignment:       4
142 tracksRegLiveness: true
143 liveins:
144   - { reg: '%rdi' }
145   - { reg: '%esi' }
146 # CHECK:  bb.0.entry:
147 # CHECK:    %eax = MOV32ri 2200000
148 # CHECK-NEXT:    %eax = FAULTING_LOAD_OP %bb.3.is_null, {{[0-9]+}}, killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x)
149 # CHECK-NEXT:    JMP_1 %bb.1.not_null
150
151 body:             |
152   bb.0.entry:
153     successors: %bb.3.is_null, %bb.1.not_null
154     liveins: %esi, %rdi
155
156     TEST64rr %rdi, %rdi, implicit-def %eflags
157     JE_1 %bb.3.is_null, implicit %eflags
158
159   bb.1.not_null:
160     successors: %bb.4.ret_100, %bb.2.ret_200
161     liveins: %esi, %rdi
162
163     %eax = MOV32ri 2200000
164     %eax = AND32rm killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x)
165     CMP32rr killed %eax, killed %esi, implicit-def %eflags
166     JE_1 %bb.4.ret_100, implicit %eflags
167
168   bb.2.ret_200:
169     %eax = MOV32ri 200
170     RET 0, %eax
171
172   bb.3.is_null:
173     %eax = MOV32ri 42
174     RET 0, %eax
175
176   bb.4.ret_100:
177     %eax = MOV32ri 100
178     RET 0, %eax
179
180 ...
181 ---
182 name:            imp_null_check_with_bitwise_op_1
183 alignment:       4
184 tracksRegLiveness: true
185 liveins:
186   - { reg: '%rdi' }
187   - { reg: '%esi' }
188   - { reg: '%rdx' }
189 # CHECK: bb.0.entry:
190 # CHECK:    %eax = MOV32rm killed %rdx, 1, _, 0, _ :: (volatile load 4 from %ir.ptr)
191 # CHECK-NEXT:    TEST64rr %rdi, %rdi, implicit-def %eflags
192 # CHECK-NEXT:    JE_1 %bb.3.is_null, implicit %eflags
193
194 body:             |
195   bb.0.entry:
196     successors: %bb.3.is_null, %bb.1.not_null
197     liveins: %esi, %rdi, %rdx
198
199     %eax = MOV32rm killed %rdx, 1, _, 0, _ :: (volatile load 4 from %ir.ptr)
200     TEST64rr %rdi, %rdi, implicit-def %eflags
201     JE_1 %bb.3.is_null, implicit %eflags
202
203   bb.1.not_null:
204     successors: %bb.4.ret_100, %bb.2.ret_200
205     liveins: %esi, %rdi
206
207     %eax = MOV32ri 2200000
208     %eax = AND32rm killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x)
209     CMP32rr killed %eax, killed %esi, implicit-def %eflags
210     JE_1 %bb.4.ret_100, implicit %eflags
211
212   bb.2.ret_200:
213     successors: %bb.3.is_null
214
215     %eax = MOV32ri 200
216
217   bb.3.is_null:
218     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
219
220     RET 0, %eax
221
222   bb.4.ret_100:
223     %eax = MOV32ri 100
224     RET 0, %eax
225
226 ...
227 ---
228 name:            imp_null_check_with_bitwise_op_2
229 # CHECK-LABEL: name:            imp_null_check_with_bitwise_op_2
230 alignment:       4
231 tracksRegLiveness: true
232 liveins:
233   - { reg: '%rdi' }
234   - { reg: '%esi' }
235 # CHECK:  bb.0.entry:
236 # CHECK:    TEST64rr %rdi, %rdi, implicit-def %eflags
237 # CHECK-NEXT:    JE_1 %bb.3.is_null, implicit %eflags
238
239 body:             |
240   bb.0.entry:
241     successors: %bb.3.is_null, %bb.1.not_null
242     liveins: %esi, %rdi
243
244     TEST64rr %rdi, %rdi, implicit-def %eflags
245     JE_1 %bb.3.is_null, implicit %eflags
246
247   bb.1.not_null:
248     successors: %bb.4.ret_100, %bb.2.ret_200
249     liveins: %esi, %rdi
250
251     %eax = MOV32ri 2200000
252     %eax = ADD32ri killed %eax, 100, implicit-def dead %eflags
253     %eax = AND32rm killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x)
254     CMP32rr killed %eax, killed %esi, implicit-def %eflags
255     JE_1 %bb.4.ret_100, implicit %eflags
256
257   bb.2.ret_200:
258     %eax = MOV32ri 200
259     RET 0, %eax
260
261   bb.3.is_null:
262     %eax = MOV32ri 42
263     RET 0, %eax
264
265   bb.4.ret_100:
266     %eax = MOV32ri 100
267     RET 0, %eax
268
269 ...
270 ---
271 name:            imp_null_check_with_bitwise_op_3
272 # CHECK-LABEL: name:            imp_null_check_with_bitwise_op_3
273 alignment:       4
274 tracksRegLiveness: true
275 liveins:
276   - { reg: '%rdi' }
277   - { reg: '%rsi' }
278 # CHECK:  bb.0.entry:
279 # CHECK:    TEST64rr %rdi, %rdi, implicit-def %eflags
280 # CHECK-NEXT:    JE_1 %bb.3.is_null, implicit %eflags
281
282 body:             |
283   bb.0.entry:
284     successors: %bb.3.is_null, %bb.1.not_null
285     liveins: %rsi, %rdi
286
287     TEST64rr %rdi, %rdi, implicit-def %eflags
288     JE_1 %bb.3.is_null, implicit %eflags
289
290   bb.1.not_null:
291     successors: %bb.4.ret_100, %bb.2.ret_200
292     liveins: %rsi, %rdi
293
294     %rdi  = MOV64ri 5000
295     %rdi = AND64rm killed %rdi, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x)
296     CMP64rr killed %rdi, killed %rsi, implicit-def %eflags
297     JE_1 %bb.4.ret_100, implicit %eflags
298
299   bb.2.ret_200:
300     %eax = MOV32ri 200
301     RET 0, %eax
302
303   bb.3.is_null:
304     %eax = MOV32ri 42
305     RET 0, %eax
306
307   bb.4.ret_100:
308     %eax = MOV32ri 100
309     RET 0, %eax
310
311 ...
312 ---
313 name:            imp_null_check_with_bitwise_op_4
314 # CHECK-LABEL: name:            imp_null_check_with_bitwise_op_4
315 alignment:       4
316 tracksRegLiveness: true
317 liveins:
318   - { reg: '%rdi' }
319   - { reg: '%rsi' }
320 # CHECK:  bb.0.entry:
321 # CHECK:  %rbx = MOV64rr %rdx
322 # CHECK-NEXT:  %rdi = FAULTING_LOAD_OP %bb.3.is_null, {{[0-9]+}}, killed %rbx, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x)
323
324 body:             |
325   bb.0.entry:
326     successors: %bb.3.is_null, %bb.1.not_null
327     liveins: %rsi, %rdi, %rdx
328
329     TEST64rr %rdi, %rdi, implicit-def %eflags
330     JE_1 %bb.3.is_null, implicit %eflags
331
332   bb.1.not_null:
333     successors: %bb.4.ret_100, %bb.2.ret_200
334     liveins: %rsi, %rdi, %rdx
335
336     %rbx  = MOV64rr %rdx
337     %rdi = AND64rm killed %rbx, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x)
338     %rdx = MOV64ri 0
339     CMP64rr killed %rdi, killed %rsi, implicit-def %eflags
340     JE_1 %bb.4.ret_100, implicit %eflags
341
342   bb.2.ret_200:
343     %eax = MOV32ri 200
344     RET 0, %eax
345
346   bb.3.is_null:
347     %eax = MOV32ri 42
348     RET 0, %eax
349
350   bb.4.ret_100:
351     %eax = MOV32ri 100
352     RET 0, %eax
353
354 ...
355 ---
356 name:            no_hoist_across_call
357 # CHECK-LABEL: name:            no_hoist_across_call
358 alignment:       4
359 tracksRegLiveness: true
360 liveins:
361   - { reg: '%rdi' }
362 calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx',
363                         '%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15',
364                         '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d',
365                         '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ]
366 # CHECK: body:
367 # CHECK-NOT: FAULTING_LOAD_OP
368 # CHECK: bb.1.stay:
369 # CHECK: CALL64pcrel32
370 body:             |
371   bb.0.entry:
372     successors: %bb.2.leave, %bb.1.stay
373     liveins: %rdi, %rbx
374
375     frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp
376     CFI_INSTRUCTION def_cfa_offset 16
377     CFI_INSTRUCTION offset %rbx, -16
378     %rbx = MOV64rr %rdi
379     TEST64rr %rbx, %rbx, implicit-def %eflags
380     JE_1 %bb.2.leave, implicit killed %eflags
381
382   bb.1.stay:
383     liveins: %rbx
384
385     CALL64pcrel32 @f, csr_64, implicit %rsp, implicit-def %rsp
386     %eax = MOV32rm killed %rbx, 1, _, 0, _ :: (load 4 from %ir.ptr)
387     %rbx = POP64r implicit-def %rsp, implicit %rsp
388     RETQ %eax
389
390   bb.2.leave:
391     %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags
392     %rbx = POP64r implicit-def %rsp, implicit %rsp
393     RETQ %eax
394
395 ...
396 ---
397 name:            dependency_live_in_hazard
398 # CHECK-LABEL: name:            dependency_live_in_hazard
399 # CHECK:   bb.0.entry:
400 # CHECK-NOT: FAULTING_LOAD_OP
401 # CHECK: bb.1.not_null:
402
403 # Make sure that the BEXTR32rm instruction below is not used to emit
404 # an implicit null check -- hoisting it will require hosting the move
405 # to %esi and we cannot do that without clobbering the use of %rsi in
406 # the first instruction in bb.1.not_null.
407 alignment:       4
408 tracksRegLiveness: true
409 liveins:
410   - { reg: '%rdi' }
411   - { reg: '%rsi' }
412 body:             |
413   bb.0.entry:
414     successors: %bb.2.is_null, %bb.1.not_null
415     liveins: %rdi, %rsi
416
417     TEST64rr %rdi, %rdi, implicit-def %eflags
418     JE_1 %bb.2.is_null, implicit killed %eflags
419
420   bb.1.not_null:
421     liveins: %rdi, %rsi
422
423     %rcx = MOV64rm killed %rsi, 1, _, 0, _ :: (load 8 from %ir.ptr2)
424     %esi = MOV32ri 3076
425     %eax = BEXTR32rm killed %rdi, 1, _, 0, _, killed %esi, implicit-def dead %eflags :: (load 4 from %ir.ptr)
426     %eax = ADD32rm killed %eax, killed %rcx, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.val)
427     RETQ %eax
428
429   bb.2.is_null:
430     %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags
431     RETQ %eax
432
433 ...