1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s | FileCheck %s --check-prefixes=ALL,CHECK
3 ; RUN: llc -O0 < %s | FileCheck %s --check-prefixes=ALL,CHECK-O0
5 ; Source to regenerate:
9 ; __attribute__((address_space(9))) int *p_other;
11 ; void use_foo(Foo *f);
12 ; void test_sign_ext(Foo *f, int * __ptr32 __sptr i) {
16 ; void test_zero_ext(Foo *f, int * __ptr32 __uptr i) {
20 ; void test_trunc(Foo *f, int * __ptr64 i) {
24 ; void test_noop1(Foo *f, int * __ptr32 i) {
28 ; void test_noop2(Foo *f, int * __ptr64 i) {
32 ; void test_null_arg(Foo *f) {
35 ; void test_unrecognized(Foo *f, __attribute__((address_space(14))) int *i) {
36 ; f->p64 = (int * __ptr64)i;
39 ; void test_unrecognized2(Foo *f, int * __ptr64 i) {
44 ; $ clang -cc1 -triple x86_64-windows-msvc -fms-extensions -O2 -S t.cpp
46 target datalayout = "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:32-n8:16:32-a:0:32-S32"
47 target triple = "i686-unknown-windows-msvc"
49 %struct.Foo = type { ptr, ptr addrspace(272), ptr addrspace(9) }
50 declare dso_local void @use_foo(ptr)
52 define dso_local void @test_sign_ext(ptr %f, ptr %i) {
53 ; CHECK-LABEL: test_sign_ext:
54 ; CHECK: # %bb.0: # %entry
55 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
56 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
57 ; CHECK-NEXT: movl %ecx, 8(%eax)
58 ; CHECK-NEXT: sarl $31, %ecx
59 ; CHECK-NEXT: movl %ecx, 12(%eax)
60 ; CHECK-NEXT: jmp _use_foo # TAILCALL
62 ; CHECK-O0-LABEL: test_sign_ext:
63 ; CHECK-O0: # %bb.0: # %entry
64 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %edx
65 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
66 ; CHECK-O0-NEXT: movl %edx, %ecx
67 ; CHECK-O0-NEXT: sarl $31, %ecx
68 ; CHECK-O0-NEXT: movl %edx, 8(%eax)
69 ; CHECK-O0-NEXT: movl %ecx, 12(%eax)
70 ; CHECK-O0-NEXT: jmp _use_foo # TAILCALL
72 %0 = addrspacecast ptr %i to ptr addrspace(272)
73 %p64 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 1
74 store ptr addrspace(272) %0, ptr %p64, align 8
75 tail call void @use_foo(ptr %f)
79 define dso_local void @test_zero_ext(ptr %f, ptr addrspace(271) %i) {
80 ; CHECK-LABEL: test_zero_ext:
81 ; CHECK: # %bb.0: # %entry
82 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
83 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
84 ; CHECK-NEXT: movl %eax, 8(%ecx)
85 ; CHECK-NEXT: movl $0, 12(%ecx)
86 ; CHECK-NEXT: jmp _use_foo # TAILCALL
88 ; CHECK-O0-LABEL: test_zero_ext:
89 ; CHECK-O0: # %bb.0: # %entry
90 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx
91 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
92 ; CHECK-O0-NEXT: movl %ecx, 8(%eax)
93 ; CHECK-O0-NEXT: movl $0, 12(%eax)
94 ; CHECK-O0-NEXT: jmp _use_foo # TAILCALL
96 %0 = addrspacecast ptr addrspace(271) %i to ptr addrspace(272)
97 %p64 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 1
98 store ptr addrspace(272) %0, ptr %p64, align 8
99 tail call void @use_foo(ptr %f)
103 define dso_local void @test_trunc(ptr %f, ptr addrspace(272) %i) {
104 ; CHECK-LABEL: test_trunc:
105 ; CHECK: # %bb.0: # %entry
106 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
107 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
108 ; CHECK-NEXT: movl %eax, (%ecx)
109 ; CHECK-NEXT: jmp _use_foo # TAILCALL
111 ; CHECK-O0-LABEL: test_trunc:
112 ; CHECK-O0: # %bb.0: # %entry
113 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
114 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx
115 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
116 ; CHECK-O0-NEXT: movl %ecx, (%eax)
117 ; CHECK-O0-NEXT: jmp _use_foo # TAILCALL
119 %0 = addrspacecast ptr addrspace(272) %i to ptr
120 store ptr %0, ptr %f, align 8
121 tail call void @use_foo(ptr %f)
125 define dso_local void @test_noop1(ptr %f, ptr %i) {
126 ; CHECK-LABEL: test_noop1:
127 ; CHECK: # %bb.0: # %entry
128 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
129 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
130 ; CHECK-NEXT: movl %eax, (%ecx)
131 ; CHECK-NEXT: jmp _use_foo # TAILCALL
133 ; CHECK-O0-LABEL: test_noop1:
134 ; CHECK-O0: # %bb.0: # %entry
135 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx
136 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
137 ; CHECK-O0-NEXT: movl %ecx, (%eax)
138 ; CHECK-O0-NEXT: jmp _use_foo # TAILCALL
140 store ptr %i, ptr %f, align 8
141 tail call void @use_foo(ptr %f)
145 define dso_local void @test_noop2(ptr %f, ptr addrspace(272) %i) {
146 ; CHECK-LABEL: test_noop2:
147 ; CHECK: # %bb.0: # %entry
148 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
149 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
150 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx
151 ; CHECK-NEXT: movl %ecx, 12(%edx)
152 ; CHECK-NEXT: movl %eax, 8(%edx)
153 ; CHECK-NEXT: jmp _use_foo # TAILCALL
155 ; CHECK-O0-LABEL: test_noop2:
156 ; CHECK-O0: # %bb.0: # %entry
157 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx
158 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %edx
159 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
160 ; CHECK-O0-NEXT: movl %edx, 8(%eax)
161 ; CHECK-O0-NEXT: movl %ecx, 12(%eax)
162 ; CHECK-O0-NEXT: jmp _use_foo # TAILCALL
164 %p64 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 1
165 store ptr addrspace(272) %i, ptr %p64, align 8
166 tail call void @use_foo(ptr %f)
170 ; Test that null can be passed as a 64-bit pointer.
171 define dso_local void @test_null_arg(ptr %f) {
172 ; CHECK-LABEL: test_null_arg:
173 ; CHECK: # %bb.0: # %entry
174 ; CHECK-NEXT: pushl $0
175 ; CHECK-NEXT: pushl $0
176 ; CHECK-NEXT: pushl {{[0-9]+}}(%esp)
177 ; CHECK-NEXT: calll _test_noop2
178 ; CHECK-NEXT: addl $12, %esp
181 ; CHECK-O0-LABEL: test_null_arg:
182 ; CHECK-O0: # %bb.0: # %entry
183 ; CHECK-O0-NEXT: subl $12, %esp
184 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx
185 ; CHECK-O0-NEXT: movl %esp, %eax
186 ; CHECK-O0-NEXT: movl %ecx, (%eax)
187 ; CHECK-O0-NEXT: movl $0, 8(%eax)
188 ; CHECK-O0-NEXT: movl $0, 4(%eax)
189 ; CHECK-O0-NEXT: calll _test_noop2
190 ; CHECK-O0-NEXT: addl $12, %esp
191 ; CHECK-O0-NEXT: retl
193 call void @test_noop2(ptr %f, ptr addrspace(272) null)
197 define dso_local void @test_unrecognized(ptr %f, ptr addrspace(14) %i) {
198 ; CHECK-LABEL: test_unrecognized:
199 ; CHECK: # %bb.0: # %entry
200 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
201 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
202 ; CHECK-NEXT: movl %ecx, 8(%eax)
203 ; CHECK-NEXT: sarl $31, %ecx
204 ; CHECK-NEXT: movl %ecx, 12(%eax)
205 ; CHECK-NEXT: jmp _use_foo # TAILCALL
207 ; CHECK-O0-LABEL: test_unrecognized:
208 ; CHECK-O0: # %bb.0: # %entry
209 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %edx
210 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
211 ; CHECK-O0-NEXT: movl %edx, %ecx
212 ; CHECK-O0-NEXT: sarl $31, %ecx
213 ; CHECK-O0-NEXT: movl %edx, 8(%eax)
214 ; CHECK-O0-NEXT: movl %ecx, 12(%eax)
215 ; CHECK-O0-NEXT: jmp _use_foo # TAILCALL
217 %0 = addrspacecast ptr addrspace(14) %i to ptr addrspace(272)
218 %p64 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 1
219 store ptr addrspace(272) %0, ptr %p64, align 8
220 tail call void @use_foo(ptr %f)
224 define dso_local void @test_unrecognized2(ptr %f, ptr addrspace(272) %i) {
225 ; CHECK-LABEL: test_unrecognized2:
226 ; CHECK: # %bb.0: # %entry
227 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
228 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
229 ; CHECK-NEXT: movl %eax, 16(%ecx)
230 ; CHECK-NEXT: jmp _use_foo # TAILCALL
232 ; CHECK-O0-LABEL: test_unrecognized2:
233 ; CHECK-O0: # %bb.0: # %entry
234 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
235 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx
236 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
237 ; CHECK-O0-NEXT: movl %ecx, 16(%eax)
238 ; CHECK-O0-NEXT: jmp _use_foo # TAILCALL
240 %0 = addrspacecast ptr addrspace(272) %i to ptr addrspace(9)
241 %p_other = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 2
242 store ptr addrspace(9) %0, ptr %p_other, align 8
243 tail call void @use_foo(ptr %f)
247 define i32 @test_load_sptr32(ptr addrspace(270) %i) {
248 ; ALL-LABEL: test_load_sptr32:
249 ; ALL: # %bb.0: # %entry
250 ; ALL-NEXT: movl {{[0-9]+}}(%esp), %eax
251 ; ALL-NEXT: movl (%eax), %eax
254 %0 = load i32, ptr addrspace(270) %i, align 4
258 define i32 @test_load_uptr32(ptr addrspace(271) %i) {
259 ; ALL-LABEL: test_load_uptr32:
260 ; ALL: # %bb.0: # %entry
261 ; ALL-NEXT: movl {{[0-9]+}}(%esp), %eax
262 ; ALL-NEXT: movl (%eax), %eax
265 %0 = load i32, ptr addrspace(271) %i, align 4
269 define i32 @test_load_ptr64(ptr addrspace(272) %i) {
270 ; CHECK-LABEL: test_load_ptr64:
271 ; CHECK: # %bb.0: # %entry
272 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
273 ; CHECK-NEXT: movl (%eax), %eax
276 ; CHECK-O0-LABEL: test_load_ptr64:
277 ; CHECK-O0: # %bb.0: # %entry
278 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
279 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
280 ; CHECK-O0-NEXT: movl (%eax), %eax
281 ; CHECK-O0-NEXT: retl
283 %0 = load i32, ptr addrspace(272) %i, align 8
287 define void @test_store_sptr32(ptr addrspace(270) %s, i32 %i) {
288 ; CHECK-LABEL: test_store_sptr32:
289 ; CHECK: # %bb.0: # %entry
290 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
291 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
292 ; CHECK-NEXT: movl %eax, (%ecx)
295 ; CHECK-O0-LABEL: test_store_sptr32:
296 ; CHECK-O0: # %bb.0: # %entry
297 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx
298 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
299 ; CHECK-O0-NEXT: movl %ecx, (%eax)
300 ; CHECK-O0-NEXT: retl
302 store i32 %i, ptr addrspace(270) %s, align 4
306 define void @test_store_uptr32(ptr addrspace(271) %s, i32 %i) {
307 ; CHECK-LABEL: test_store_uptr32:
308 ; CHECK: # %bb.0: # %entry
309 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
310 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
311 ; CHECK-NEXT: movl %eax, (%ecx)
314 ; CHECK-O0-LABEL: test_store_uptr32:
315 ; CHECK-O0: # %bb.0: # %entry
316 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx
317 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
318 ; CHECK-O0-NEXT: movl %ecx, (%eax)
319 ; CHECK-O0-NEXT: retl
321 store i32 %i, ptr addrspace(271) %s, align 4
325 define void @test_store_ptr64(ptr addrspace(272) %s, i32 %i) {
326 ; CHECK-LABEL: test_store_ptr64:
327 ; CHECK: # %bb.0: # %entry
328 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
329 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
330 ; CHECK-NEXT: movl %eax, (%ecx)
333 ; CHECK-O0-LABEL: test_store_ptr64:
334 ; CHECK-O0: # %bb.0: # %entry
335 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
336 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
337 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx
338 ; CHECK-O0-NEXT: movl %ecx, (%eax)
339 ; CHECK-O0-NEXT: retl
341 store i32 %i, ptr addrspace(272) %s, align 8
345 define i64 @test_load_sptr32_zext_i64(ptr addrspace(270) %i) {
346 ; ALL-LABEL: test_load_sptr32_zext_i64:
347 ; ALL: # %bb.0: # %entry
348 ; ALL-NEXT: movl {{[0-9]+}}(%esp), %eax
349 ; ALL-NEXT: movl (%eax), %eax
350 ; ALL-NEXT: xorl %edx, %edx
353 %0 = load i32, ptr addrspace(270) %i, align 4
354 %1 = zext i32 %0 to i64
358 define void @test_store_sptr32_trunc_i1(ptr addrspace(270) %s, i32 %i) {
359 ; CHECK-LABEL: test_store_sptr32_trunc_i1:
360 ; CHECK: # %bb.0: # %entry
361 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
362 ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
363 ; CHECK-NEXT: andl $1, %ecx
364 ; CHECK-NEXT: movb %cl, (%eax)
367 ; CHECK-O0-LABEL: test_store_sptr32_trunc_i1:
368 ; CHECK-O0: # %bb.0: # %entry
369 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx
370 ; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax
371 ; CHECK-O0-NEXT: andl $1, %ecx
372 ; CHECK-O0-NEXT: # kill: def $cl killed $cl killed $ecx
373 ; CHECK-O0-NEXT: movb %cl, (%eax)
374 ; CHECK-O0-NEXT: retl
376 %0 = trunc i32 %i to i1
377 store i1 %0, ptr addrspace(270) %s