Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / test / CodeGen / X86 / implicit-null-check.ll
blob8cfc9c669ad03beee8bfb0c22faa0aec1f147401
1 ; RUN: llc -verify-machineinstrs -O3 -mtriple=x86_64-apple-macosx -enable-implicit-null-checks < %s | FileCheck %s
3 ; RUN: llc < %s -mtriple=x86_64-apple-macosx -enable-implicit-null-checks \
4 ; RUN:    | llvm-mc -triple x86_64-apple-macosx -filetype=obj -o - \
5 ; RUN:    | llvm-objdump -triple x86_64-apple-macosx -fault-map-section - \
6 ; RUN:    | FileCheck %s -check-prefix OBJDUMP
8 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -enable-implicit-null-checks \
9 ; RUN:    | llvm-mc -triple x86_64-unknown-linux-gnu -filetype=obj -o - \
10 ; RUN:    | llvm-objdump -triple x86_64-unknown-linux-gnu -fault-map-section - \
11 ; RUN:    | FileCheck %s -check-prefix OBJDUMP
13 define i32 @imp_null_check_load(i32* %x) {
14 ; CHECK-LABEL: _imp_null_check_load:
15 ; CHECK: [[BB0_imp_null_check_load:L[^:]+]]:
16 ; CHECK: movl (%rdi), %eax
17 ; CHECK: retq
18 ; CHECK: [[BB1_imp_null_check_load:LBB0_[0-9]+]]:
19 ; CHECK: movl $42, %eax
20 ; CHECK: retq
22  entry:
23   %c = icmp eq i32* %x, null
24   br i1 %c, label %is_null, label %not_null, !make.implicit !0
26  is_null:
27   ret i32 42
29  not_null:
30   %t = load i32, i32* %x
31   ret i32 %t
34 define i32 @imp_null_check_gep_load(i32* %x) {
35 ; CHECK-LABEL: _imp_null_check_gep_load:
36 ; CHECK: [[BB0_imp_null_check_gep_load:L[^:]+]]:
37 ; CHECK: movl 128(%rdi), %eax
38 ; CHECK: retq
39 ; CHECK: [[BB1_imp_null_check_gep_load:LBB1_[0-9]+]]:
40 ; CHECK: movl $42, %eax
41 ; CHECK: retq
43  entry:
44   %c = icmp eq i32* %x, null
45   br i1 %c, label %is_null, label %not_null, !make.implicit !0
47  is_null:
48   ret i32 42
50  not_null:
51   %x.gep = getelementptr i32, i32* %x, i32 32
52   %t = load i32, i32* %x.gep
53   ret i32 %t
56 define i32 @imp_null_check_add_result(i32* %x, i32 %p) {
57 ; CHECK-LABEL: _imp_null_check_add_result:
58 ; CHECK: [[BB0_imp_null_check_add_result:L[^:]+]]:
59 ; CHECK: addl (%rdi), %esi
60 ; CHECK: movl %esi, %eax
61 ; CHECK: retq
62 ; CHECK: [[BB1_imp_null_check_add_result:LBB2_[0-9]+]]:
63 ; CHECK: movl $42, %eax
64 ; CHECK: retq
66  entry:
67   %c = icmp eq i32* %x, null
68   br i1 %c, label %is_null, label %not_null, !make.implicit !0
70  is_null:
71   ret i32 42
73  not_null:
74   %t = load i32, i32* %x
75   %p1 = add i32 %t, %p
76   ret i32 %p1
79 define i32 @imp_null_check_hoist_over_unrelated_load(i32* %x, i32* %y, i32* %z) {
80 ; CHECK-LABEL: _imp_null_check_hoist_over_unrelated_load:
81 ; CHECK: [[BB0_imp_null_check_hoist_over_unrelated_load:L[^:]+]]:
82 ; CHECK: movl (%rdi), %eax
83 ; CHECK: movl (%rsi), %ecx
84 ; CHECK: movl %ecx, (%rdx)
85 ; CHECK: retq
86 ; CHECK: [[BB1_imp_null_check_hoist_over_unrelated_load:LBB3_[0-9]+]]:
87 ; CHECK: movl   $42, %eax
88 ; CHECK: retq
90  entry:
91   %c = icmp eq i32* %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   %t0 = load i32, i32* %y
99   %t1 = load i32, i32* %x
100   store i32 %t0, i32* %z
101   ret i32 %t1
104 define i32 @imp_null_check_via_mem_comparision(i32* %x, i32 %val) {
105 ; CHECK-LABEL: _imp_null_check_via_mem_comparision
106 ; CHECK: [[BB0_imp_null_check_via_mem_comparision:L[^:]+]]:
107 ; CHECK: cmpl   %esi, 4(%rdi)
108 ; CHECK: jge    LBB4_2
109 ; CHECK: movl   $100, %eax
110 ; CHECK: retq
111 ; CHECK: [[BB1_imp_null_check_via_mem_comparision:LBB4_[0-9]+]]:
112 ; CHECK: movl   $42, %eax
113 ; CHECK: retq
114 ; CHECK: LBB4_2:
115 ; CHECK: movl   $200, %eax
116 ; CHECK: retq
118  entry:
119   %c = icmp eq i32* %x, null
120   br i1 %c, label %is_null, label %not_null, !make.implicit !0
122  is_null:
123   ret i32 42
125  not_null:
126   %x.loc = getelementptr i32, i32* %x, i32 1
127   %t = load i32, i32* %x.loc
128   %m = icmp slt i32 %t, %val
129   br i1 %m, label %ret_100, label %ret_200
131  ret_100:
132   ret i32 100
134  ret_200:
135   ret i32 200
138 define i32 @imp_null_check_gep_load_with_use_dep(i32* %x, i32 %a) {
139 ; CHECK-LABEL: imp_null_check_gep_load_with_use_dep:
140 ; CHECK: [[BB0_imp_null_check_gep_load_with_use_dep:L[^:]+]]:
141 ; CHECK: movl (%rdi), %eax
142 ; CHECK: addl %edi, %esi
143 ; CHECK: leal 4(%rax,%rsi), %eax
144 ; CHECK: retq
145 ; CHECK: [[BB1_imp_null_check_gep_load_with_use_dep:LBB5_[0-9]+]]:
146 ; CHECK: movl $42, %eax
147 ; CHECK: retq
149  entry:
150   %c = icmp eq i32* %x, null
151   br i1 %c, label %is_null, label %not_null, !make.implicit !0
153  is_null:
154   ret i32 42
156  not_null:
157   %x.loc = getelementptr i32, i32* %x, i32 1
158   %y = ptrtoint i32* %x.loc to i32
159   %b = add i32 %a, %y
160   %t = load i32, i32* %x
161   %z = add i32 %t, %b
162   ret i32 %z
165 define void @imp_null_check_store(i32* %x) {
166 ; CHECK-LABEL: _imp_null_check_store:
167 ; CHECK: [[BB0_imp_null_check_store:L[^:]+]]:
168 ; CHECK: movl $1, (%rdi)
169 ; CHECK: retq
170 ; CHECK: [[BB1_imp_null_check_store:LBB6_[0-9]+]]:
171 ; CHECK: retq
173  entry:
174   %c = icmp eq i32* %x, null
175   br i1 %c, label %is_null, label %not_null, !make.implicit !0
177  is_null:
178   ret void
180  not_null:
181   store i32 1, i32* %x
182   ret void
185 define i32 @imp_null_check_neg_gep_load(i32* %x) {
186 ; CHECK-LABEL: _imp_null_check_neg_gep_load:
187 ; CHECK: [[BB0_imp_null_check_neg_gep_load:L[^:]+]]:
188 ; CHECK: movl -128(%rdi), %eax
189 ; CHECK: retq
190 ; CHECK: [[BB1_imp_null_check_neg_gep_load:LBB7_[0-9]+]]:
191 ; CHECK: movl $42, %eax
192 ; CHECK: retq
194  entry:
195   %c = icmp eq i32* %x, null
196   br i1 %c, label %is_null, label %not_null, !make.implicit !0
198  is_null:
199   ret i32 42
201  not_null:
202   %x.gep = getelementptr i32, i32* %x, i32 -32
203   %t = load i32, i32* %x.gep
204   ret i32 %t
207 !0 = !{}
209 ; CHECK-LABEL: __LLVM_FaultMaps:
211 ; Version:
212 ; CHECK-NEXT: .byte 1
214 ; Reserved x2
215 ; CHECK-NEXT: .byte 0
216 ; CHECK-NEXT: .short 0
218 ; # functions:
219 ; CHECK-NEXT: .long 8
221 ; FunctionAddr:
222 ; CHECK-NEXT: .quad _imp_null_check_add_result
223 ; NumFaultingPCs
224 ; CHECK-NEXT: .long 1
225 ; Reserved:
226 ; CHECK-NEXT: .long 0
227 ; Fault[0].Type:
228 ; CHECK-NEXT: .long 1
229 ; Fault[0].FaultOffset:
230 ; CHECK-NEXT: .long [[BB0_imp_null_check_add_result]]-_imp_null_check_add_result
231 ; Fault[0].HandlerOffset:
232 ; CHECK-NEXT: .long [[BB1_imp_null_check_add_result]]-_imp_null_check_add_result
234 ; FunctionAddr:
235 ; CHECK-NEXT: .quad _imp_null_check_gep_load
236 ; NumFaultingPCs
237 ; CHECK-NEXT: .long 1
238 ; Reserved:
239 ; CHECK-NEXT: .long 0
240 ; Fault[0].Type:
241 ; CHECK-NEXT: .long 1
242 ; Fault[0].FaultOffset:
243 ; CHECK-NEXT: .long [[BB0_imp_null_check_gep_load]]-_imp_null_check_gep_load
244 ; Fault[0].HandlerOffset:
245 ; CHECK-NEXT: .long [[BB1_imp_null_check_gep_load]]-_imp_null_check_gep_load
247 ; FunctionAddr:
248 ; CHECK-NEXT: .quad _imp_null_check_gep_load_with_use_dep
249 ; NumFaultingPCs
250 ; CHECK-NEXT: .long 1
251 ; Reserved:
252 ; CHECK-NEXT: .long 0
253 ; Fault[0].Type:
254 ; CHECK-NEXT: .long 1
255 ; Fault[0].FaultOffset:
256 ; CHECK-NEXT: .long [[BB0_imp_null_check_gep_load_with_use_dep]]-_imp_null_check_gep_load_with_use_dep
257 ; Fault[0].HandlerOffset:
258 ; CHECK-NEXT: .long [[BB1_imp_null_check_gep_load_with_use_dep]]-_imp_null_check_gep_load_with_use_dep
260 ; FunctionAddr:
261 ; CHECK-NEXT: .quad _imp_null_check_hoist_over_unrelated_load
262 ; NumFaultingPCs
263 ; CHECK-NEXT: .long 1
264 ; Reserved:
265 ; CHECK-NEXT: .long 0
266 ; Fault[0].Type:
267 ; CHECK-NEXT: .long 1
268 ; Fault[0].FaultOffset:
269 ; CHECK-NEXT: .long [[BB0_imp_null_check_hoist_over_unrelated_load]]-_imp_null_check_hoist_over_unrelated_load
270 ; Fault[0].HandlerOffset:
271 ; CHECK-NEXT: .long [[BB1_imp_null_check_hoist_over_unrelated_load]]-_imp_null_check_hoist_over_unrelated_load
273 ; FunctionAddr:
274 ; CHECK-NEXT: .quad _imp_null_check_load
275 ; NumFaultingPCs
276 ; CHECK-NEXT: .long 1
277 ; Reserved:
278 ; CHECK-NEXT: .long 0
279 ; Fault[0].Type:
280 ; CHECK-NEXT: .long 1
281 ; Fault[0].FaultOffset:
282 ; CHECK-NEXT: .long [[BB0_imp_null_check_load]]-_imp_null_check_load
283 ; Fault[0].HandlerOffset:
284 ; CHECK-NEXT: .long [[BB1_imp_null_check_load]]-_imp_null_check_load
286 ; FunctionAddr:
287 ; CHECK-NEXT: .quad _imp_null_check_neg_gep_load
288 ; NumFaultingPCs
289 ; CHECK-NEXT: .long 1
290 ; Reserved:
291 ; CHECK-NEXT: .long 0
292 ; Fault[0].Type:
293 ; CHECK-NEXT: .long 1
294 ; Fault[0].FaultOffset:
295 ; CHECK-NEXT: .long [[BB0_imp_null_check_neg_gep_load]]-_imp_null_check_neg_gep_load
296 ; Fault[0].HandlerOffset:
297 ; CHECK-NEXT: .long [[BB1_imp_null_check_neg_gep_load]]-_imp_null_check_neg_gep_load
299 ; FunctionAddr:
300 ; CHECK-NEXT: .quad _imp_null_check_store
301 ; NumFaultingPCs
302 ; CHECK-NEXT: .long 1
303 ; Reserved:
304 ; CHECK-NEXT: .long 0
305 ; Fault[0].Type:
306 ; CHECK-NEXT: .long 3
307 ; Fault[0].FaultOffset:
308 ; CHECK-NEXT: .long [[BB0_imp_null_check_store]]-_imp_null_check_store
309 ; Fault[0].HandlerOffset:
310 ; CHECK-NEXT: .long [[BB1_imp_null_check_store]]-_imp_null_check_store
312 ; FunctionAddr:
313 ; CHECK-NEXT: .quad     _imp_null_check_via_mem_comparision
314 ; NumFaultingPCs
315 ; CHECK-NEXT: .long   1
316 ; Reserved:
317 ; CHECK-NEXT: .long   0
318 ; Fault[0].Type:
319 ; CHECK-NEXT: .long   1
320 ; Fault[0].FaultOffset:
321 ; CHECK-NEXT: .long   [[BB0_imp_null_check_via_mem_comparision]]-_imp_null_check_via_mem_comparision
322 ; Fault[0].HandlerOffset:
323 ; CHECK-NEXT: .long   [[BB1_imp_null_check_via_mem_comparision]]-_imp_null_check_via_mem_comparision
325 ; OBJDUMP: FaultMap table:
326 ; OBJDUMP-NEXT: Version: 0x1
327 ; OBJDUMP-NEXT: NumFunctions: 8
328 ; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1
329 ; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 5
330 ; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1
331 ; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 7
332 ; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1
333 ; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 9
334 ; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1
335 ; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 7
336 ; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1
337 ; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 3
338 ; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1
339 ; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 4
340 ; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1
341 ; OBJDUMP-NEXT: Fault kind: FaultingStore, faulting PC offset: 0, handling PC offset: 7
342 ; OBJDUMP-NEXT: FunctionAddress: 0x000000, NumFaultingPCs: 1
343 ; OBJDUMP-NEXT: Fault kind: FaultingLoad, faulting PC offset: 0, handling PC offset: 11