xref: /llvm-project/llvm/test/CodeGen/X86/mixed-ptr-sizes-i686.ll (revision 0dcc65359b3d7c9725144bc58599faacf2ab2d88)
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
4
5; Source to regenerate:
6; struct Foo {
7;   int * __ptr32 p32;
8;   int * __ptr64 p64;
9;   __attribute__((address_space(9))) int *p_other;
10; };
11; void use_foo(Foo *f);
12; void test_sign_ext(Foo *f, int * __ptr32 __sptr i) {
13;   f->p64 = i;
14;   use_foo(f);
15; }
16; void test_zero_ext(Foo *f, int * __ptr32 __uptr i) {
17;   f->p64 = i;
18;   use_foo(f);
19; }
20; void test_trunc(Foo *f, int * __ptr64 i) {
21;   f->p32 = i;
22;   use_foo(f);
23; }
24; void test_noop1(Foo *f, int * __ptr32 i) {
25;   f->p32 = i;
26;   use_foo(f);
27; }
28; void test_noop2(Foo *f, int * __ptr64 i) {
29;   f->p64 = i;
30;   use_foo(f);
31; }
32; void test_null_arg(Foo *f) {
33;   test_noop2(f, 0);
34; }
35; void test_unrecognized(Foo *f, __attribute__((address_space(14))) int *i) {
36;   f->p64 = (int * __ptr64)i;
37;   use_foo(f);
38; }
39; void test_unrecognized2(Foo *f, int * __ptr64 i) {
40;   f->p_other = i;
41;   use_foo(f);
42; }
43;
44; $ clang -cc1 -triple x86_64-windows-msvc -fms-extensions -O2 -S t.cpp
45
46target 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"
47target triple = "i686-unknown-windows-msvc"
48
49%struct.Foo = type { ptr, ptr addrspace(272), ptr addrspace(9) }
50declare dso_local void @use_foo(ptr)
51
52define 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
61;
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
71entry:
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)
76  ret void
77}
78
79define 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
87;
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
95entry:
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)
100  ret void
101}
102
103define 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
110;
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
118entry:
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)
122  ret void
123}
124
125define 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
132;
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
139entry:
140  store ptr %i, ptr %f, align 8
141  tail call void @use_foo(ptr %f)
142  ret void
143}
144
145define 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
154;
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
163entry:
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)
167  ret void
168}
169
170; Test that null can be passed as a 64-bit pointer.
171define 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
179; CHECK-NEXT:    retl
180;
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
192entry:
193  call void @test_noop2(ptr %f, ptr addrspace(272) null)
194  ret void
195}
196
197define 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
206;
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
216entry:
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)
221  ret void
222}
223
224define 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
231;
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
239entry:
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)
244  ret void
245}
246
247define 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
252; ALL-NEXT:    retl
253entry:
254  %0 = load i32, ptr addrspace(270) %i, align 4
255  ret i32 %0
256}
257
258define 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
263; ALL-NEXT:    retl
264entry:
265  %0 = load i32, ptr addrspace(271) %i, align 4
266  ret i32 %0
267}
268
269define 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
274; CHECK-NEXT:    retl
275;
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
282entry:
283  %0 = load i32, ptr addrspace(272) %i, align 8
284  ret i32 %0
285}
286
287define 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)
293; CHECK-NEXT:    retl
294;
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
301entry:
302  store i32 %i, ptr addrspace(270) %s, align 4
303  ret void
304}
305
306define 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)
312; CHECK-NEXT:    retl
313;
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
320entry:
321  store i32 %i, ptr addrspace(271) %s, align 4
322  ret void
323}
324
325define 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)
331; CHECK-NEXT:    retl
332;
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
340entry:
341  store i32 %i, ptr addrspace(272) %s, align 8
342  ret void
343}
344
345define 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
351; ALL-NEXT:    retl
352entry:
353  %0 = load i32, ptr addrspace(270) %i, align 4
354  %1 = zext i32 %0 to i64
355  ret i64 %1
356}
357
358define 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)
365; CHECK-NEXT:    retl
366;
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
375entry:
376  %0 = trunc i32 %i to i1
377  store i1 %0, ptr addrspace(270) %s
378  ret void
379}
380