[AArch64,ELF] Restrict MOVZ/MOVK to non-PIC large code model (#70178)
[llvm-project.git] / llvm / test / CodeGen / X86 / mixed-ptr-sizes.ll
blob67539b07f5716c197bc23faed523afe2bf818a51
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:
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, int * __ptr32 i) {
33 ;   test_noop1(f, 0);
34 ; }
35 ; void test_unrecognized(Foo *f, __attribute__((address_space(14))) int *i) {
36 ;   f->p32 = (int * __ptr32)i;
37 ;   use_foo(f);
38 ; }
40 ; $ clang -cc1 -triple x86_64-windows-msvc -fms-extensions -O2 -S t.cpp
42 target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
43 target triple = "x86_64-unknown-windows-msvc"
45 %struct.Foo = type { ptr addrspace(270), ptr, ptr addrspace(9) }
46 declare dso_local void @use_foo(ptr)
48 define dso_local void @test_sign_ext(ptr %f, ptr addrspace(270) %i) {
49 ; ALL-LABEL: test_sign_ext:
50 ; ALL:       # %bb.0: # %entry
51 ; ALL-NEXT:    movslq %edx, %rax
52 ; ALL-NEXT:    movq %rax, 8(%rcx)
53 ; ALL-NEXT:    jmp use_foo # TAILCALL
54 entry:
55   %0 = addrspacecast ptr addrspace(270) %i to ptr
56   %p64 = getelementptr inbounds %struct.Foo, ptr %f, i64 0, i32 1
57   store ptr %0, ptr %p64, align 8
58   tail call void @use_foo(ptr %f)
59   ret void
62 define dso_local void @test_zero_ext(ptr %f, ptr addrspace(271) %i) {
63 ; CHECK-LABEL: test_zero_ext:
64 ; CHECK:       # %bb.0: # %entry
65 ; CHECK-NEXT:    movl %edx, %eax
66 ; CHECK-NEXT:    movq %rax, 8(%rcx)
67 ; CHECK-NEXT:    jmp use_foo # TAILCALL
69 ; CHECK-O0-LABEL: test_zero_ext:
70 ; CHECK-O0:       # %bb.0: # %entry
71 ; CHECK-O0-NEXT:    movl %edx, %eax
72 ; CHECK-O0-NEXT:    # kill: def $rax killed $eax
73 ; CHECK-O0-NEXT:    movq %rax, 8(%rcx)
74 ; CHECK-O0-NEXT:    jmp use_foo # TAILCALL
75 entry:
76   %0 = addrspacecast ptr addrspace(271) %i to ptr
77   %p64 = getelementptr inbounds %struct.Foo, ptr %f, i64 0, i32 1
78   store ptr %0, ptr %p64, align 8
79   tail call void @use_foo(ptr %f)
80   ret void
83 define dso_local void @test_trunc(ptr %f, ptr %i) {
84 ; CHECK-LABEL: test_trunc:
85 ; CHECK:       # %bb.0: # %entry
86 ; CHECK-NEXT:    movl %edx, (%rcx)
87 ; CHECK-NEXT:    jmp use_foo # TAILCALL
89 ; CHECK-O0-LABEL: test_trunc:
90 ; CHECK-O0:       # %bb.0: # %entry
91 ; CHECK-O0-NEXT:    movl %edx, %eax
92 ; CHECK-O0-NEXT:    movl %eax, (%rcx)
93 ; CHECK-O0-NEXT:    jmp use_foo # TAILCALL
94 entry:
95   %0 = addrspacecast ptr %i to ptr addrspace(270)
96   store ptr addrspace(270) %0, ptr %f, align 8
97   tail call void @use_foo(ptr %f)
98   ret void
101 define dso_local void @test_noop1(ptr %f, ptr addrspace(270) %i) {
102 ; ALL-LABEL: test_noop1:
103 ; ALL:       # %bb.0: # %entry
104 ; ALL-NEXT:    movl %edx, (%rcx)
105 ; ALL-NEXT:    jmp use_foo # TAILCALL
106 entry:
107   store ptr addrspace(270) %i, ptr %f, align 8
108   tail call void @use_foo(ptr %f)
109   ret void
112 define dso_local void @test_noop2(ptr %f, ptr %i) {
113 ; ALL-LABEL: test_noop2:
114 ; ALL:       # %bb.0: # %entry
115 ; ALL-NEXT:    movq %rdx, 8(%rcx)
116 ; ALL-NEXT:    jmp use_foo # TAILCALL
117 entry:
118   %p64 = getelementptr inbounds %struct.Foo, ptr %f, i64 0, i32 1
119   store ptr %i, ptr %p64, align 8
120   tail call void @use_foo(ptr %f)
121   ret void
124 ; Test that null can be passed as a 32-bit pointer.
125 define dso_local void @test_null_arg(ptr %f) {
126 ; ALL-LABEL: test_null_arg:
127 ; ALL:       # %bb.0: # %entry
128 ; ALL-NEXT:    subq $40, %rsp
129 ; ALL-NEXT:    .seh_stackalloc 40
130 ; ALL-NEXT:    .seh_endprologue
131 ; ALL-NEXT:    xorl %edx, %edx
132 ; ALL-NEXT:    callq test_noop1
133 ; ALL-NEXT:    nop
134 ; ALL-NEXT:    addq $40, %rsp
135 ; ALL-NEXT:    retq
136 ; ALL-NEXT:    .seh_endproc
137 entry:
138   call void @test_noop1(ptr %f, ptr addrspace(270) null)
139   ret void
142 ; Test casts between unrecognized address spaces.
143 define void @test_unrecognized(ptr %f, ptr addrspace(14) %i) {
144 ; CHECK-LABEL: test_unrecognized:
145 ; CHECK:       # %bb.0: # %entry
146 ; CHECK-NEXT:    movl %edx, (%rcx)
147 ; CHECK-NEXT:    jmp use_foo # TAILCALL
149 ; CHECK-O0-LABEL: test_unrecognized:
150 ; CHECK-O0:       # %bb.0: # %entry
151 ; CHECK-O0-NEXT:    movl %edx, %eax
152 ; CHECK-O0-NEXT:    movl %eax, (%rcx)
153 ; CHECK-O0-NEXT:    jmp use_foo # TAILCALL
154 entry:
155   %0 = addrspacecast ptr addrspace(14) %i to ptr addrspace(270)
156   store ptr addrspace(270) %0, ptr %f, align 8
157   tail call void @use_foo(ptr %f)
158   ret void
161 define void @test_unrecognized2(ptr %f, ptr addrspace(271) %i) {
162 ; CHECK-LABEL: test_unrecognized2:
163 ; CHECK:       # %bb.0: # %entry
164 ; CHECK-NEXT:    movl %edx, %eax
165 ; CHECK-NEXT:    movq %rax, 16(%rcx)
166 ; CHECK-NEXT:    jmp use_foo # TAILCALL
168 ; CHECK-O0-LABEL: test_unrecognized2:
169 ; CHECK-O0:       # %bb.0: # %entry
170 ; CHECK-O0-NEXT:    movl %edx, %eax
171 ; CHECK-O0-NEXT:    # kill: def $rax killed $eax
172 ; CHECK-O0-NEXT:    movq %rax, 16(%rcx)
173 ; CHECK-O0-NEXT:    jmp use_foo # TAILCALL
174 entry:
175   %0 = addrspacecast ptr addrspace(271) %i to ptr addrspace(9)
176   %p32 = getelementptr inbounds %struct.Foo, ptr %f, i64 0, i32 2
177   store ptr addrspace(9) %0, ptr %p32, align 8
178   tail call void @use_foo(ptr %f)
179   ret void
182 define i32 @test_load_sptr32(ptr addrspace(270) %i) {
183 ; ALL-LABEL: test_load_sptr32:
184 ; ALL:       # %bb.0: # %entry
185 ; ALL-NEXT:    movslq %ecx, %rax
186 ; ALL-NEXT:    movl (%rax), %eax
187 ; ALL-NEXT:    retq
188 entry:
189   %0 = load i32, ptr addrspace(270) %i, align 4
190   ret i32 %0
193 define i32 @test_load_uptr32(ptr addrspace(271) %i) {
194 ; CHECK-LABEL: test_load_uptr32:
195 ; CHECK:       # %bb.0: # %entry
196 ; CHECK-NEXT:    movl %ecx, %eax
197 ; CHECK-NEXT:    movl (%rax), %eax
198 ; CHECK-NEXT:    retq
200 ; CHECK-O0-LABEL: test_load_uptr32:
201 ; CHECK-O0:       # %bb.0: # %entry
202 ; CHECK-O0-NEXT:    movl %ecx, %eax
203 ; CHECK-O0-NEXT:    # kill: def $rax killed $eax
204 ; CHECK-O0-NEXT:    movl (%rax), %eax
205 ; CHECK-O0-NEXT:    retq
206 entry:
207   %0 = load i32, ptr addrspace(271) %i, align 4
208   ret i32 %0
211 define i32 @test_load_ptr64(ptr addrspace(272) %i) {
212 ; ALL-LABEL: test_load_ptr64:
213 ; ALL:       # %bb.0: # %entry
214 ; ALL-NEXT:    movl (%rcx), %eax
215 ; ALL-NEXT:    retq
216 entry:
217   %0 = load i32, ptr addrspace(272) %i, align 8
218   ret i32 %0
221 define void @test_store_sptr32(ptr addrspace(270) %s, i32 %i) {
222 ; ALL-LABEL: test_store_sptr32:
223 ; ALL:       # %bb.0: # %entry
224 ; ALL-NEXT:    movslq %ecx, %rax
225 ; ALL-NEXT:    movl %edx, (%rax)
226 ; ALL-NEXT:    retq
227 entry:
228   store i32 %i, ptr addrspace(270) %s, align 4
229   ret void
232 define void @test_store_uptr32(ptr addrspace(271) %s, i32 %i) {
233 ; CHECK-LABEL: test_store_uptr32:
234 ; CHECK:       # %bb.0: # %entry
235 ; CHECK-NEXT:    movl %ecx, %eax
236 ; CHECK-NEXT:    movl %edx, (%rax)
237 ; CHECK-NEXT:    retq
239 ; CHECK-O0-LABEL: test_store_uptr32:
240 ; CHECK-O0:       # %bb.0: # %entry
241 ; CHECK-O0-NEXT:    movl %ecx, %eax
242 ; CHECK-O0-NEXT:    # kill: def $rax killed $eax
243 ; CHECK-O0-NEXT:    movl %edx, (%rax)
244 ; CHECK-O0-NEXT:    retq
245 entry:
246   store i32 %i, ptr addrspace(271) %s, align 4
247   ret void
250 define void @test_store_ptr64(ptr addrspace(272) %s, i32 %i) {
251 ; ALL-LABEL: test_store_ptr64:
252 ; ALL:       # %bb.0: # %entry
253 ; ALL-NEXT:    movl %edx, (%rcx)
254 ; ALL-NEXT:    retq
255 entry:
256   store i32 %i, ptr addrspace(272) %s, align 8
257   ret void
260 define i64 @test_load_sptr32_zext_i64(ptr addrspace(270) %i) {
261 ; CHECK-LABEL: test_load_sptr32_zext_i64:
262 ; CHECK:       # %bb.0: # %entry
263 ; CHECK-NEXT:    movslq %ecx, %rax
264 ; CHECK-NEXT:    movl (%rax), %eax
265 ; CHECK-NEXT:    retq
267 ; CHECK-O0-LABEL: test_load_sptr32_zext_i64:
268 ; CHECK-O0:       # %bb.0: # %entry
269 ; CHECK-O0-NEXT:    movslq %ecx, %rax
270 ; CHECK-O0-NEXT:    movl (%rax), %eax
271 ; CHECK-O0-NEXT:    movl %eax, %eax
272 ; CHECK-O0-NEXT:    # kill: def $rax killed $eax
273 ; CHECK-O0-NEXT:    retq
274 entry:
275   %0 = load i32, ptr addrspace(270) %i, align 4
276   %1 = zext i32 %0 to i64
277   ret i64 %1
280 define void @test_store_sptr32_trunc_i1(ptr addrspace(270) %s, i32 %i) {
281 ; CHECK-LABEL: test_store_sptr32_trunc_i1:
282 ; CHECK:       # %bb.0: # %entry
283 ; CHECK-NEXT:    movslq %ecx, %rax
284 ; CHECK-NEXT:    andl $1, %edx
285 ; CHECK-NEXT:    movb %dl, (%rax)
286 ; CHECK-NEXT:    retq
288 ; CHECK-O0-LABEL: test_store_sptr32_trunc_i1:
289 ; CHECK-O0:       # %bb.0: # %entry
290 ; CHECK-O0-NEXT:    movslq %ecx, %rax
291 ; CHECK-O0-NEXT:    andl $1, %edx
292 ; CHECK-O0-NEXT:    movb %dl, %cl
293 ; CHECK-O0-NEXT:    movb %cl, (%rax)
294 ; CHECK-O0-NEXT:    retq
295 entry:
296   %0 = trunc i32 %i to i1
297   store i1 %0, ptr addrspace(270) %s
298   ret void