AMDGPU: Fix v16i32 to v16i8 truncstore
[oota-llvm.git] / test / CodeGen / AMDGPU / cgp-addressing-modes.ll
1 ; RUN: opt -S -codegenprepare -mtriple=amdgcn-unknown-unknown -mcpu=bonaire < %s | FileCheck -check-prefix=OPT -check-prefix=OPT-CI %s
2 ; RUN: opt -S -codegenprepare -mtriple=amdgcn-unknown-unknown -mcpu=tonga < %s | FileCheck -check-prefix=OPT -check-prefix=OPT-VI %s
3 ; RUN: llc -march=amdgcn -mcpu=bonaire -mattr=-promote-alloca < %s | FileCheck -check-prefix=GCN -check-prefix=CI %s
4 ; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-promote-alloca < %s | FileCheck -check-prefix=GCN -check-prefix=VI %s
5
6 declare i32 @llvm.r600.read.tidig.x() #0
7
8 ; OPT-LABEL: @test_sink_global_small_offset_i32(
9 ; OPT-CI-NOT: getelementptr i32, i32 addrspace(1)* %in
10 ; OPT-VI: getelementptr i32, i32 addrspace(1)* %in
11 ; OPT: br i1
12 ; OPT-CI: ptrtoint
13
14 ; GCN-LABEL: {{^}}test_sink_global_small_offset_i32:
15 ; GCN: {{^}}BB0_2:
16 define void @test_sink_global_small_offset_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %cond) {
17 entry:
18   %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999
19   %in.gep = getelementptr i32, i32 addrspace(1)* %in, i64 7
20   %tmp0 = icmp eq i32 %cond, 0
21   br i1 %tmp0, label %endif, label %if
22
23 if:
24   %tmp1 = load i32, i32 addrspace(1)* %in.gep
25   br label %endif
26
27 endif:
28   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
29   store i32 %x, i32 addrspace(1)* %out.gep
30   br label %done
31
32 done:
33   ret void
34 }
35
36 ; OPT-LABEL: @test_sink_global_small_max_i32_ds_offset(
37 ; OPT: %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 65535
38 ; OPT: br i1
39
40 ; GCN-LABEL: {{^}}test_sink_global_small_max_i32_ds_offset:
41 ; GCN: s_and_saveexec_b64
42 ; GCN: buffer_load_sbyte {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, s{{[0-9]+$}}
43 ; GCN: {{^}}BB1_2:
44 ; GCN: s_or_b64 exec
45 define void @test_sink_global_small_max_i32_ds_offset(i32 addrspace(1)* %out, i8 addrspace(1)* %in, i32 %cond) {
46 entry:
47   %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 99999
48   %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 65535
49   %tmp0 = icmp eq i32 %cond, 0
50   br i1 %tmp0, label %endif, label %if
51
52 if:
53   %tmp1 = load i8, i8 addrspace(1)* %in.gep
54   %tmp2 = sext i8 %tmp1 to i32
55   br label %endif
56
57 endif:
58   %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
59   store i32 %x, i32 addrspace(1)* %out.gep
60   br label %done
61
62 done:
63   ret void
64 }
65
66 ; GCN-LABEL: {{^}}test_sink_global_small_max_mubuf_offset:
67 ; GCN: s_and_saveexec_b64
68 ; GCN: buffer_load_sbyte {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0 offset:4095{{$}}
69 ; GCN: {{^}}BB2_2:
70 ; GCN: s_or_b64 exec
71 define void @test_sink_global_small_max_mubuf_offset(i32 addrspace(1)* %out, i8 addrspace(1)* %in, i32 %cond) {
72 entry:
73   %out.gep = getelementptr i32, i32 addrspace(1)* %out, i32 1024
74   %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 4095
75   %tmp0 = icmp eq i32 %cond, 0
76   br i1 %tmp0, label %endif, label %if
77
78 if:
79   %tmp1 = load i8, i8 addrspace(1)* %in.gep
80   %tmp2 = sext i8 %tmp1 to i32
81   br label %endif
82
83 endif:
84   %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
85   store i32 %x, i32 addrspace(1)* %out.gep
86   br label %done
87
88 done:
89   ret void
90 }
91
92 ; GCN-LABEL: {{^}}test_sink_global_small_max_plus_1_mubuf_offset:
93 ; GCN: s_and_saveexec_b64
94 ; GCN: buffer_load_sbyte {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, s{{[0-9]+$}}
95 ; GCN: {{^}}BB3_2:
96 ; GCN: s_or_b64 exec
97 define void @test_sink_global_small_max_plus_1_mubuf_offset(i32 addrspace(1)* %out, i8 addrspace(1)* %in, i32 %cond) {
98 entry:
99   %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 99999
100   %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 4096
101   %tmp0 = icmp eq i32 %cond, 0
102   br i1 %tmp0, label %endif, label %if
103
104 if:
105   %tmp1 = load i8, i8 addrspace(1)* %in.gep
106   %tmp2 = sext i8 %tmp1 to i32
107   br label %endif
108
109 endif:
110   %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
111   store i32 %x, i32 addrspace(1)* %out.gep
112   br label %done
113
114 done:
115   ret void
116 }
117
118 ; OPT-LABEL: @test_no_sink_flat_small_offset_i32(
119 ; OPT: getelementptr i32, i32 addrspace(4)* %in
120 ; OPT: br i1
121 ; OPT-NOT: ptrtoint
122
123 ; GCN-LABEL: {{^}}test_no_sink_flat_small_offset_i32:
124 ; GCN: flat_load_dword
125 ; GCN: {{^}}BB4_2:
126
127 define void @test_no_sink_flat_small_offset_i32(i32 addrspace(4)* %out, i32 addrspace(4)* %in, i32 %cond) {
128 entry:
129   %out.gep = getelementptr i32, i32 addrspace(4)* %out, i64 999999
130   %in.gep = getelementptr i32, i32 addrspace(4)* %in, i64 7
131   %tmp0 = icmp eq i32 %cond, 0
132   br i1 %tmp0, label %endif, label %if
133
134 if:
135   %tmp1 = load i32, i32 addrspace(4)* %in.gep
136   br label %endif
137
138 endif:
139   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
140   store i32 %x, i32 addrspace(4)* %out.gep
141   br label %done
142
143 done:
144   ret void
145 }
146
147 ; OPT-LABEL: @test_sink_scratch_small_offset_i32(
148 ; OPT-NOT:  getelementptr [512 x i32]
149 ; OPT: br i1
150 ; OPT: ptrtoint
151
152 ; GCN-LABEL: {{^}}test_sink_scratch_small_offset_i32:
153 ; GCN: s_and_saveexec_b64
154 ; GCN: buffer_store_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen offset:4092{{$}}
155 ; GCN: buffer_load_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen offset:4092{{$}}
156 ; GCN: {{^}}BB5_2:
157 define void @test_sink_scratch_small_offset_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %cond, i32 %arg) {
158 entry:
159   %alloca = alloca [512 x i32], align 4
160   %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i64 999998
161   %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i64 999999
162   %add.arg = add i32 %arg, 8
163   %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1023
164   %tmp0 = icmp eq i32 %cond, 0
165   br i1 %tmp0, label %endif, label %if
166
167 if:
168   store volatile i32 123, i32* %alloca.gep
169   %tmp1 = load volatile i32, i32* %alloca.gep
170   br label %endif
171
172 endif:
173   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
174   store i32 %x, i32 addrspace(1)* %out.gep.0
175   %load = load volatile i32, i32* %alloca.gep
176   store i32 %load, i32 addrspace(1)* %out.gep.1
177   br label %done
178
179 done:
180   ret void
181 }
182
183 ; OPT-LABEL: @test_no_sink_scratch_large_offset_i32(
184 ; OPT: %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1024
185 ; OPT: br i1
186 ; OPT-NOT: ptrtoint
187
188 ; GCN-LABEL: {{^}}test_no_sink_scratch_large_offset_i32:
189 ; GCN: s_and_saveexec_b64
190 ; GCN: buffer_store_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen{{$}}
191 ; GCN: buffer_load_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen{{$}}
192 ; GCN: {{^}}BB6_2:
193 define void @test_no_sink_scratch_large_offset_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %cond, i32 %arg) {
194 entry:
195   %alloca = alloca [512 x i32], align 4
196   %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i64 999998
197   %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i64 999999
198   %add.arg = add i32 %arg, 8
199   %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1024
200   %tmp0 = icmp eq i32 %cond, 0
201   br i1 %tmp0, label %endif, label %if
202
203 if:
204   store volatile i32 123, i32* %alloca.gep
205   %tmp1 = load volatile i32, i32* %alloca.gep
206   br label %endif
207
208 endif:
209   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
210   store i32 %x, i32 addrspace(1)* %out.gep.0
211   %load = load volatile i32, i32* %alloca.gep
212   store i32 %load, i32 addrspace(1)* %out.gep.1
213   br label %done
214
215 done:
216   ret void
217 }
218
219 ; GCN-LABEL: {{^}}test_sink_global_vreg_sreg_i32:
220 ; VI-DAG: s_movk_i32 flat_scratch_lo, 0x0
221 ; VI-DAG: s_movk_i32 flat_scratch_hi, 0x0
222 ; GCN: s_and_saveexec_b64
223 ; CI: buffer_load_dword {{v[0-9]+}}, {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64{{$}}
224 ; VI: flat_load_dword v{{[0-9]+}}, v[{{[0-9]+:[0-9]+}}]
225 ; GCN: {{^}}BB7_2:
226 define void @test_sink_global_vreg_sreg_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %offset, i32 %cond) {
227 entry:
228   %offset.ext = zext i32 %offset to i64
229   %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999
230   %in.gep = getelementptr i32, i32 addrspace(1)* %in, i64 %offset.ext
231   %tmp0 = icmp eq i32 %cond, 0
232   br i1 %tmp0, label %endif, label %if
233
234 if:
235   %tmp1 = load i32, i32 addrspace(1)* %in.gep
236   br label %endif
237
238 endif:
239   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
240   store i32 %x, i32 addrspace(1)* %out.gep
241   br label %done
242
243 done:
244   ret void
245 }
246
247 attributes #0 = { nounwind readnone }
248 attributes #1 = { nounwind }