R600/SI: Use unordered not equal instructions
[oota-llvm.git] / test / CodeGen / R600 / setcc.ll
1 ; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -check-prefix=R600 -check-prefix=FUNC %s
2 ; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
3
4 declare i32 @llvm.r600.read.tidig.x() nounwind readnone
5
6 ; FUNC-LABEL: {{^}}setcc_v2i32:
7 ; R600-DAG: SETE_INT * T{{[0-9]+\.[XYZW]}}, KC0[3].X, KC0[3].Z
8 ; R600-DAG: SETE_INT * T{{[0-9]+\.[XYZW]}}, KC0[2].W, KC0[3].Y
9
10 define void @setcc_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> %a, <2 x i32> %b) {
11   %result = icmp eq <2 x i32> %a, %b
12   %sext = sext <2 x i1> %result to <2 x i32>
13   store <2 x i32> %sext, <2 x i32> addrspace(1)* %out
14   ret void
15 }
16
17 ; FUNC-LABEL: {{^}}setcc_v4i32:
18 ; R600-DAG: SETE_INT * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
19 ; R600-DAG: SETE_INT * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
20 ; R600-DAG: SETE_INT * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
21 ; R600-DAG: SETE_INT * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
22
23 define void @setcc_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %in) {
24   %b_ptr = getelementptr <4 x i32> addrspace(1)* %in, i32 1
25   %a = load <4 x i32> addrspace(1) * %in
26   %b = load <4 x i32> addrspace(1) * %b_ptr
27   %result = icmp eq <4 x i32> %a, %b
28   %sext = sext <4 x i1> %result to <4 x i32>
29   store <4 x i32> %sext, <4 x i32> addrspace(1)* %out
30   ret void
31 }
32
33 ;;;==========================================================================;;;
34 ;; Float comparisons
35 ;;;==========================================================================;;;
36
37 ; FUNC-LABEL: {{^}}f32_oeq:
38 ; R600: SETE_DX10
39 ; SI: v_cmp_eq_f32
40 define void @f32_oeq(i32 addrspace(1)* %out, float %a, float %b) {
41 entry:
42   %0 = fcmp oeq float %a, %b
43   %1 = sext i1 %0 to i32
44   store i32 %1, i32 addrspace(1)* %out
45   ret void
46 }
47
48 ; FUNC-LABEL: {{^}}f32_ogt:
49 ; R600: SETGT_DX10
50 ; SI: v_cmp_gt_f32
51 define void @f32_ogt(i32 addrspace(1)* %out, float %a, float %b) {
52 entry:
53   %0 = fcmp ogt float %a, %b
54   %1 = sext i1 %0 to i32
55   store i32 %1, i32 addrspace(1)* %out
56   ret void
57 }
58
59 ; FUNC-LABEL: {{^}}f32_oge:
60 ; R600: SETGE_DX10
61 ; SI: v_cmp_ge_f32
62 define void @f32_oge(i32 addrspace(1)* %out, float %a, float %b) {
63 entry:
64   %0 = fcmp oge float %a, %b
65   %1 = sext i1 %0 to i32
66   store i32 %1, i32 addrspace(1)* %out
67   ret void
68 }
69
70 ; FUNC-LABEL: {{^}}f32_olt:
71 ; R600: SETGT_DX10
72 ; SI: v_cmp_lt_f32
73 define void @f32_olt(i32 addrspace(1)* %out, float %a, float %b) {
74 entry:
75   %0 = fcmp olt float %a, %b
76   %1 = sext i1 %0 to i32
77   store i32 %1, i32 addrspace(1)* %out
78   ret void
79 }
80
81 ; FUNC-LABEL: {{^}}f32_ole:
82 ; R600: SETGE_DX10
83 ; SI: v_cmp_le_f32
84 define void @f32_ole(i32 addrspace(1)* %out, float %a, float %b) {
85 entry:
86   %0 = fcmp ole float %a, %b
87   %1 = sext i1 %0 to i32
88   store i32 %1, i32 addrspace(1)* %out
89   ret void
90 }
91
92 ; FUNC-LABEL: {{^}}f32_one:
93 ; R600-DAG: SETE_DX10
94 ; R600-DAG: SETE_DX10
95 ; R600-DAG: AND_INT
96 ; R600-DAG: SETNE_DX10
97 ; R600-DAG: AND_INT
98 ; R600-DAG: SETNE_INT
99
100 ; SI: v_cmp_lg_f32_e32 vcc
101 ; SI-NEXT: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1, vcc
102 define void @f32_one(i32 addrspace(1)* %out, float %a, float %b) {
103 entry:
104   %0 = fcmp one float %a, %b
105   %1 = sext i1 %0 to i32
106   store i32 %1, i32 addrspace(1)* %out
107   ret void
108 }
109
110 ; FUNC-LABEL: {{^}}f32_ord:
111 ; R600-DAG: SETE_DX10
112 ; R600-DAG: SETE_DX10
113 ; R600-DAG: AND_INT
114 ; R600-DAG: SETNE_INT
115 ; SI: v_cmp_o_f32
116 define void @f32_ord(i32 addrspace(1)* %out, float %a, float %b) {
117 entry:
118   %0 = fcmp ord float %a, %b
119   %1 = sext i1 %0 to i32
120   store i32 %1, i32 addrspace(1)* %out
121   ret void
122 }
123
124 ; FUNC-LABEL: {{^}}f32_ueq:
125 ; R600-DAG: SETNE_DX10
126 ; R600-DAG: SETNE_DX10
127 ; R600-DAG: OR_INT
128 ; R600-DAG: SETE_DX10
129 ; R600-DAG: OR_INT
130 ; R600-DAG: SETNE_INT
131
132 ; SI-DAG: v_cmp_u_f32_e32 vcc
133 ; SI-DAG: v_cmp_eq_f32_e64 [[CMP1:s\[[0-9]+:[0-9]+\]]]
134 ; SI: s_or_b64 [[OR:s\[[0-9]+:[0-9]+\]]], [[CMP1]], vcc
135 ; SI: v_cndmask_b32_e64 [[VRESULT:v[0-9]+]], 0, -1, [[OR]]
136 ; SI: buffer_store_dword [[VRESULT]]
137 define void @f32_ueq(i32 addrspace(1)* %out, float %a, float %b) {
138 entry:
139   %0 = fcmp ueq float %a, %b
140   %1 = sext i1 %0 to i32
141   store i32 %1, i32 addrspace(1)* %out
142   ret void
143 }
144
145 ; FUNC-LABEL: {{^}}f32_ugt:
146 ; R600: SETGE
147 ; R600: SETE_DX10
148 ; SI: v_cmp_u_f32
149 ; SI: v_cmp_gt_f32
150 ; SI: s_or_b64
151 ; SI: v_cndmask_b32
152 define void @f32_ugt(i32 addrspace(1)* %out, float %a, float %b) {
153 entry:
154   %0 = fcmp ugt float %a, %b
155   %1 = sext i1 %0 to i32
156   store i32 %1, i32 addrspace(1)* %out
157   ret void
158 }
159
160 ; FUNC-LABEL: {{^}}f32_uge:
161 ; R600: SETGT
162 ; R600: SETE_DX10
163 ; SI: v_cmp_u_f32
164 ; SI: v_cmp_ge_f32
165 ; SI: s_or_b64
166 ; SI: v_cndmask_b32
167 define void @f32_uge(i32 addrspace(1)* %out, float %a, float %b) {
168 entry:
169   %0 = fcmp uge float %a, %b
170   %1 = sext i1 %0 to i32
171   store i32 %1, i32 addrspace(1)* %out
172   ret void
173 }
174
175 ; FUNC-LABEL: {{^}}f32_ult:
176 ; R600: SETGE
177 ; R600: SETE_DX10
178 ; SI: v_cmp_u_f32
179 ; SI: v_cmp_lt_f32
180 ; SI: s_or_b64
181 ; SI: v_cndmask_b32
182 define void @f32_ult(i32 addrspace(1)* %out, float %a, float %b) {
183 entry:
184   %0 = fcmp ult float %a, %b
185   %1 = sext i1 %0 to i32
186   store i32 %1, i32 addrspace(1)* %out
187   ret void
188 }
189
190 ; FUNC-LABEL: {{^}}f32_ule:
191 ; R600: SETGT
192 ; R600: SETE_DX10
193 ; SI: v_cmp_u_f32
194 ; SI: v_cmp_le_f32
195 ; SI: s_or_b64
196 ; SI: v_cndmask_b32
197 define void @f32_ule(i32 addrspace(1)* %out, float %a, float %b) {
198 entry:
199   %0 = fcmp ule float %a, %b
200   %1 = sext i1 %0 to i32
201   store i32 %1, i32 addrspace(1)* %out
202   ret void
203 }
204
205 ; FUNC-LABEL: {{^}}f32_une:
206 ; R600: SETNE_DX10
207 ; SI: v_cmp_neq_f32
208 define void @f32_une(i32 addrspace(1)* %out, float %a, float %b) {
209 entry:
210   %0 = fcmp une float %a, %b
211   %1 = sext i1 %0 to i32
212   store i32 %1, i32 addrspace(1)* %out
213   ret void
214 }
215
216 ; FUNC-LABEL: {{^}}f32_uno:
217 ; R600: SETNE_DX10
218 ; R600: SETNE_DX10
219 ; R600: OR_INT
220 ; R600: SETNE_INT
221 ; SI: v_cmp_u_f32
222 define void @f32_uno(i32 addrspace(1)* %out, float %a, float %b) {
223 entry:
224   %0 = fcmp uno float %a, %b
225   %1 = sext i1 %0 to i32
226   store i32 %1, i32 addrspace(1)* %out
227   ret void
228 }
229
230 ;;;==========================================================================;;;
231 ;; 32-bit integer comparisons
232 ;;;==========================================================================;;;
233
234 ; FUNC-LABEL: {{^}}i32_eq:
235 ; R600: SETE_INT
236 ; SI: v_cmp_eq_i32
237 define void @i32_eq(i32 addrspace(1)* %out, i32 %a, i32 %b) {
238 entry:
239   %0 = icmp eq i32 %a, %b
240   %1 = sext i1 %0 to i32
241   store i32 %1, i32 addrspace(1)* %out
242   ret void
243 }
244
245 ; FUNC-LABEL: {{^}}i32_ne:
246 ; R600: SETNE_INT
247 ; SI: v_cmp_ne_i32
248 define void @i32_ne(i32 addrspace(1)* %out, i32 %a, i32 %b) {
249 entry:
250   %0 = icmp ne i32 %a, %b
251   %1 = sext i1 %0 to i32
252   store i32 %1, i32 addrspace(1)* %out
253   ret void
254 }
255
256 ; FUNC-LABEL: {{^}}i32_ugt:
257 ; R600: SETGT_UINT
258 ; SI: v_cmp_gt_u32
259 define void @i32_ugt(i32 addrspace(1)* %out, i32 %a, i32 %b) {
260 entry:
261   %0 = icmp ugt i32 %a, %b
262   %1 = sext i1 %0 to i32
263   store i32 %1, i32 addrspace(1)* %out
264   ret void
265 }
266
267 ; FUNC-LABEL: {{^}}i32_uge:
268 ; R600: SETGE_UINT
269 ; SI: v_cmp_ge_u32
270 define void @i32_uge(i32 addrspace(1)* %out, i32 %a, i32 %b) {
271 entry:
272   %0 = icmp uge i32 %a, %b
273   %1 = sext i1 %0 to i32
274   store i32 %1, i32 addrspace(1)* %out
275   ret void
276 }
277
278 ; FUNC-LABEL: {{^}}i32_ult:
279 ; R600: SETGT_UINT
280 ; SI: v_cmp_lt_u32
281 define void @i32_ult(i32 addrspace(1)* %out, i32 %a, i32 %b) {
282 entry:
283   %0 = icmp ult i32 %a, %b
284   %1 = sext i1 %0 to i32
285   store i32 %1, i32 addrspace(1)* %out
286   ret void
287 }
288
289 ; FUNC-LABEL: {{^}}i32_ule:
290 ; R600: SETGE_UINT
291 ; SI: v_cmp_le_u32
292 define void @i32_ule(i32 addrspace(1)* %out, i32 %a, i32 %b) {
293 entry:
294   %0 = icmp ule i32 %a, %b
295   %1 = sext i1 %0 to i32
296   store i32 %1, i32 addrspace(1)* %out
297   ret void
298 }
299
300 ; FUNC-LABEL: {{^}}i32_sgt:
301 ; R600: SETGT_INT
302 ; SI: v_cmp_gt_i32
303 define void @i32_sgt(i32 addrspace(1)* %out, i32 %a, i32 %b) {
304 entry:
305   %0 = icmp sgt i32 %a, %b
306   %1 = sext i1 %0 to i32
307   store i32 %1, i32 addrspace(1)* %out
308   ret void
309 }
310
311 ; FUNC-LABEL: {{^}}i32_sge:
312 ; R600: SETGE_INT
313 ; SI: v_cmp_ge_i32
314 define void @i32_sge(i32 addrspace(1)* %out, i32 %a, i32 %b) {
315 entry:
316   %0 = icmp sge i32 %a, %b
317   %1 = sext i1 %0 to i32
318   store i32 %1, i32 addrspace(1)* %out
319   ret void
320 }
321
322 ; FUNC-LABEL: {{^}}i32_slt:
323 ; R600: SETGT_INT
324 ; SI: v_cmp_lt_i32
325 define void @i32_slt(i32 addrspace(1)* %out, i32 %a, i32 %b) {
326 entry:
327   %0 = icmp slt i32 %a, %b
328   %1 = sext i1 %0 to i32
329   store i32 %1, i32 addrspace(1)* %out
330   ret void
331 }
332
333 ; FUNC-LABEL: {{^}}i32_sle:
334 ; R600: SETGE_INT
335 ; SI: v_cmp_le_i32
336 define void @i32_sle(i32 addrspace(1)* %out, i32 %a, i32 %b) {
337 entry:
338   %0 = icmp sle i32 %a, %b
339   %1 = sext i1 %0 to i32
340   store i32 %1, i32 addrspace(1)* %out
341   ret void
342 }
343
344 ; FIXME: This does 4 compares
345 ; FUNC-LABEL: {{^}}v3i32_eq:
346 ; SI-DAG: v_cmp_eq_i32
347 ; SI-DAG: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1,
348 ; SI-DAG: v_cmp_eq_i32
349 ; SI-DAG: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1,
350 ; SI-DAG: v_cmp_eq_i32
351 ; SI-DAG: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1,
352 ; SI: s_endpgm
353 define void @v3i32_eq(<3 x i32> addrspace(1)* %out, <3 x i32> addrspace(1)* %ptra, <3 x i32> addrspace(1)* %ptrb) {
354   %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
355   %gep.a = getelementptr <3 x i32> addrspace(1)* %ptra, i32 %tid
356   %gep.b = getelementptr <3 x i32> addrspace(1)* %ptrb, i32 %tid
357   %gep.out = getelementptr <3 x i32> addrspace(1)* %out, i32 %tid
358   %a = load <3 x i32> addrspace(1)* %gep.a
359   %b = load <3 x i32> addrspace(1)* %gep.b
360   %cmp = icmp eq <3 x i32> %a, %b
361   %ext = sext <3 x i1> %cmp to <3 x i32>
362   store <3 x i32> %ext, <3 x i32> addrspace(1)* %gep.out
363   ret void
364 }
365
366 ; FUNC-LABEL: {{^}}v3i8_eq:
367 ; SI-DAG: v_cmp_eq_i32
368 ; SI-DAG: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1,
369 ; SI-DAG: v_cmp_eq_i32
370 ; SI-DAG: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1,
371 ; SI-DAG: v_cmp_eq_i32
372 ; SI-DAG: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1,
373 ; SI: s_endpgm
374 define void @v3i8_eq(<3 x i8> addrspace(1)* %out, <3 x i8> addrspace(1)* %ptra, <3 x i8> addrspace(1)* %ptrb) {
375   %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
376   %gep.a = getelementptr <3 x i8> addrspace(1)* %ptra, i32 %tid
377   %gep.b = getelementptr <3 x i8> addrspace(1)* %ptrb, i32 %tid
378   %gep.out = getelementptr <3 x i8> addrspace(1)* %out, i32 %tid
379   %a = load <3 x i8> addrspace(1)* %gep.a
380   %b = load <3 x i8> addrspace(1)* %gep.b
381   %cmp = icmp eq <3 x i8> %a, %b
382   %ext = sext <3 x i1> %cmp to <3 x i8>
383   store <3 x i8> %ext, <3 x i8> addrspace(1)* %gep.out
384   ret void
385 }