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, int * __ptr32 i) {
35 ; void test_unrecognized(Foo *f, __attribute__((address_space(14))) int *i) {
36 ; f->p32 = (int * __ptr32)i;
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 { i32 addrspace(270)*, i32*, i32 addrspace(9)* }
46 declare dso_local void @use_foo(%struct.Foo*)
48 define dso_local void @test_sign_ext(%struct.Foo* %f, i32 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
55 %0 = addrspacecast i32 addrspace(270)* %i to i32*
56 %p64 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 1
57 store i32* %0, i32** %p64, align 8
58 tail call void @use_foo(%struct.Foo* %f)
62 define dso_local void @test_zero_ext(%struct.Foo* %f, i32 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
76 %0 = addrspacecast i32 addrspace(271)* %i to i32*
77 %p64 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 1
78 store i32* %0, i32** %p64, align 8
79 tail call void @use_foo(%struct.Foo* %f)
83 define dso_local void @test_trunc(%struct.Foo* %f, i32* %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
95 %0 = addrspacecast i32* %i to i32 addrspace(270)*
96 %p32 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 0
97 store i32 addrspace(270)* %0, i32 addrspace(270)** %p32, align 8
98 tail call void @use_foo(%struct.Foo* %f)
102 define dso_local void @test_noop1(%struct.Foo* %f, i32 addrspace(270)* %i) {
103 ; ALL-LABEL: test_noop1:
104 ; ALL: # %bb.0: # %entry
105 ; ALL-NEXT: movl %edx, (%rcx)
106 ; ALL-NEXT: jmp use_foo # TAILCALL
108 %p32 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 0
109 store i32 addrspace(270)* %i, i32 addrspace(270)** %p32, align 8
110 tail call void @use_foo(%struct.Foo* %f)
114 define dso_local void @test_noop2(%struct.Foo* %f, i32* %i) {
115 ; ALL-LABEL: test_noop2:
116 ; ALL: # %bb.0: # %entry
117 ; ALL-NEXT: movq %rdx, 8(%rcx)
118 ; ALL-NEXT: jmp use_foo # TAILCALL
120 %p64 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 1
121 store i32* %i, i32** %p64, align 8
122 tail call void @use_foo(%struct.Foo* %f)
126 ; Test that null can be passed as a 32-bit pointer.
127 define dso_local void @test_null_arg(%struct.Foo* %f) {
128 ; ALL-LABEL: test_null_arg:
129 ; ALL: # %bb.0: # %entry
130 ; ALL-NEXT: subq $40, %rsp
131 ; ALL-NEXT: .seh_stackalloc 40
132 ; ALL-NEXT: .seh_endprologue
133 ; ALL-NEXT: xorl %edx, %edx
134 ; ALL-NEXT: callq test_noop1
136 ; ALL-NEXT: addq $40, %rsp
138 ; ALL-NEXT: .seh_endproc
140 call void @test_noop1(%struct.Foo* %f, i32 addrspace(270)* null)
144 ; Test casts between unrecognized address spaces.
145 define void @test_unrecognized(%struct.Foo* %f, i32 addrspace(14)* %i) {
146 ; CHECK-LABEL: test_unrecognized:
147 ; CHECK: # %bb.0: # %entry
148 ; CHECK-NEXT: movl %edx, (%rcx)
149 ; CHECK-NEXT: jmp use_foo # TAILCALL
151 ; CHECK-O0-LABEL: test_unrecognized:
152 ; CHECK-O0: # %bb.0: # %entry
153 ; CHECK-O0-NEXT: movl %edx, %eax
154 ; CHECK-O0-NEXT: movl %eax, (%rcx)
155 ; CHECK-O0-NEXT: jmp use_foo # TAILCALL
157 %0 = addrspacecast i32 addrspace(14)* %i to i32 addrspace(270)*
158 %p32 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 0
159 store i32 addrspace(270)* %0, i32 addrspace(270)** %p32, align 8
160 tail call void @use_foo(%struct.Foo* %f)
164 define void @test_unrecognized2(%struct.Foo* %f, i32 addrspace(271)* %i) {
165 ; CHECK-LABEL: test_unrecognized2:
166 ; CHECK: # %bb.0: # %entry
167 ; CHECK-NEXT: movl %edx, %eax
168 ; CHECK-NEXT: movq %rax, 16(%rcx)
169 ; CHECK-NEXT: jmp use_foo # TAILCALL
171 ; CHECK-O0-LABEL: test_unrecognized2:
172 ; CHECK-O0: # %bb.0: # %entry
173 ; CHECK-O0-NEXT: movl %edx, %eax
174 ; CHECK-O0-NEXT: # kill: def $rax killed $eax
175 ; CHECK-O0-NEXT: movq %rax, 16(%rcx)
176 ; CHECK-O0-NEXT: jmp use_foo # TAILCALL
178 %0 = addrspacecast i32 addrspace(271)* %i to i32 addrspace(9)*
179 %p32 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 2
180 store i32 addrspace(9)* %0, i32 addrspace(9)** %p32, align 8
181 tail call void @use_foo(%struct.Foo* %f)
185 define i32 @test_load_sptr32(i32 addrspace(270)* %i) {
186 ; ALL-LABEL: test_load_sptr32:
187 ; ALL: # %bb.0: # %entry
188 ; ALL-NEXT: movslq %ecx, %rax
189 ; ALL-NEXT: movl (%rax), %eax
192 %0 = load i32, i32 addrspace(270)* %i, align 4
196 define i32 @test_load_uptr32(i32 addrspace(271)* %i) {
197 ; CHECK-LABEL: test_load_uptr32:
198 ; CHECK: # %bb.0: # %entry
199 ; CHECK-NEXT: movl %ecx, %eax
200 ; CHECK-NEXT: movl (%rax), %eax
203 ; CHECK-O0-LABEL: test_load_uptr32:
204 ; CHECK-O0: # %bb.0: # %entry
205 ; CHECK-O0-NEXT: movl %ecx, %eax
206 ; CHECK-O0-NEXT: # kill: def $rax killed $eax
207 ; CHECK-O0-NEXT: movl (%rax), %eax
208 ; CHECK-O0-NEXT: retq
210 %0 = load i32, i32 addrspace(271)* %i, align 4
214 define i32 @test_load_ptr64(i32 addrspace(272)* %i) {
215 ; ALL-LABEL: test_load_ptr64:
216 ; ALL: # %bb.0: # %entry
217 ; ALL-NEXT: movl (%rcx), %eax
220 %0 = load i32, i32 addrspace(272)* %i, align 8
224 define void @test_store_sptr32(i32 addrspace(270)* %s, i32 %i) {
225 ; ALL-LABEL: test_store_sptr32:
226 ; ALL: # %bb.0: # %entry
227 ; ALL-NEXT: movslq %ecx, %rax
228 ; ALL-NEXT: movl %edx, (%rax)
231 store i32 %i, i32 addrspace(270)* %s, align 4
235 define void @test_store_uptr32(i32 addrspace(271)* %s, i32 %i) {
236 ; CHECK-LABEL: test_store_uptr32:
237 ; CHECK: # %bb.0: # %entry
238 ; CHECK-NEXT: movl %ecx, %eax
239 ; CHECK-NEXT: movl %edx, (%rax)
242 ; CHECK-O0-LABEL: test_store_uptr32:
243 ; CHECK-O0: # %bb.0: # %entry
244 ; CHECK-O0-NEXT: movl %ecx, %eax
245 ; CHECK-O0-NEXT: # kill: def $rax killed $eax
246 ; CHECK-O0-NEXT: movl %edx, (%rax)
247 ; CHECK-O0-NEXT: retq
249 store i32 %i, i32 addrspace(271)* %s, align 4
253 define void @test_store_ptr64(i32 addrspace(272)* %s, i32 %i) {
254 ; ALL-LABEL: test_store_ptr64:
255 ; ALL: # %bb.0: # %entry
256 ; ALL-NEXT: movl %edx, (%rcx)
259 store i32 %i, i32 addrspace(272)* %s, align 8