R600/SI: Make more unordered comparisons legal
[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_nle_f32_e32 vcc
149 ; SI-NEXT: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1, vcc
150 define void @f32_ugt(i32 addrspace(1)* %out, float %a, float %b) {
151 entry:
152   %0 = fcmp ugt float %a, %b
153   %1 = sext i1 %0 to i32
154   store i32 %1, i32 addrspace(1)* %out
155   ret void
156 }
157
158 ; FUNC-LABEL: {{^}}f32_uge:
159 ; R600: SETGT
160 ; R600: SETE_DX10
161
162 ; SI: v_cmp_nlt_f32_e32 vcc
163 ; SI-NEXT: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1, vcc
164 define void @f32_uge(i32 addrspace(1)* %out, float %a, float %b) {
165 entry:
166   %0 = fcmp uge float %a, %b
167   %1 = sext i1 %0 to i32
168   store i32 %1, i32 addrspace(1)* %out
169   ret void
170 }
171
172 ; FUNC-LABEL: {{^}}f32_ult:
173 ; R600: SETGE
174 ; R600: SETE_DX10
175
176 ; SI: v_cmp_nge_f32_e32 vcc
177 ; SI-NEXT: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1, vcc
178 define void @f32_ult(i32 addrspace(1)* %out, float %a, float %b) {
179 entry:
180   %0 = fcmp ult float %a, %b
181   %1 = sext i1 %0 to i32
182   store i32 %1, i32 addrspace(1)* %out
183   ret void
184 }
185
186 ; FUNC-LABEL: {{^}}f32_ule:
187 ; R600: SETGT
188 ; R600: SETE_DX10
189
190 ; SI: v_cmp_ngt_f32_e32 vcc
191 ; SI-NEXT: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1, vcc
192 define void @f32_ule(i32 addrspace(1)* %out, float %a, float %b) {
193 entry:
194   %0 = fcmp ule float %a, %b
195   %1 = sext i1 %0 to i32
196   store i32 %1, i32 addrspace(1)* %out
197   ret void
198 }
199
200 ; FUNC-LABEL: {{^}}f32_une:
201 ; R600: SETNE_DX10
202 ; SI: v_cmp_neq_f32
203 define void @f32_une(i32 addrspace(1)* %out, float %a, float %b) {
204 entry:
205   %0 = fcmp une float %a, %b
206   %1 = sext i1 %0 to i32
207   store i32 %1, i32 addrspace(1)* %out
208   ret void
209 }
210
211 ; FUNC-LABEL: {{^}}f32_uno:
212 ; R600: SETNE_DX10
213 ; R600: SETNE_DX10
214 ; R600: OR_INT
215 ; R600: SETNE_INT
216 ; SI: v_cmp_u_f32
217 define void @f32_uno(i32 addrspace(1)* %out, float %a, float %b) {
218 entry:
219   %0 = fcmp uno float %a, %b
220   %1 = sext i1 %0 to i32
221   store i32 %1, i32 addrspace(1)* %out
222   ret void
223 }
224
225 ;;;==========================================================================;;;
226 ;; 32-bit integer comparisons
227 ;;;==========================================================================;;;
228
229 ; FUNC-LABEL: {{^}}i32_eq:
230 ; R600: SETE_INT
231 ; SI: v_cmp_eq_i32
232 define void @i32_eq(i32 addrspace(1)* %out, i32 %a, i32 %b) {
233 entry:
234   %0 = icmp eq i32 %a, %b
235   %1 = sext i1 %0 to i32
236   store i32 %1, i32 addrspace(1)* %out
237   ret void
238 }
239
240 ; FUNC-LABEL: {{^}}i32_ne:
241 ; R600: SETNE_INT
242 ; SI: v_cmp_ne_i32
243 define void @i32_ne(i32 addrspace(1)* %out, i32 %a, i32 %b) {
244 entry:
245   %0 = icmp ne i32 %a, %b
246   %1 = sext i1 %0 to i32
247   store i32 %1, i32 addrspace(1)* %out
248   ret void
249 }
250
251 ; FUNC-LABEL: {{^}}i32_ugt:
252 ; R600: SETGT_UINT
253 ; SI: v_cmp_gt_u32
254 define void @i32_ugt(i32 addrspace(1)* %out, i32 %a, i32 %b) {
255 entry:
256   %0 = icmp ugt i32 %a, %b
257   %1 = sext i1 %0 to i32
258   store i32 %1, i32 addrspace(1)* %out
259   ret void
260 }
261
262 ; FUNC-LABEL: {{^}}i32_uge:
263 ; R600: SETGE_UINT
264 ; SI: v_cmp_ge_u32
265 define void @i32_uge(i32 addrspace(1)* %out, i32 %a, i32 %b) {
266 entry:
267   %0 = icmp uge i32 %a, %b
268   %1 = sext i1 %0 to i32
269   store i32 %1, i32 addrspace(1)* %out
270   ret void
271 }
272
273 ; FUNC-LABEL: {{^}}i32_ult:
274 ; R600: SETGT_UINT
275 ; SI: v_cmp_lt_u32
276 define void @i32_ult(i32 addrspace(1)* %out, i32 %a, i32 %b) {
277 entry:
278   %0 = icmp ult i32 %a, %b
279   %1 = sext i1 %0 to i32
280   store i32 %1, i32 addrspace(1)* %out
281   ret void
282 }
283
284 ; FUNC-LABEL: {{^}}i32_ule:
285 ; R600: SETGE_UINT
286 ; SI: v_cmp_le_u32
287 define void @i32_ule(i32 addrspace(1)* %out, i32 %a, i32 %b) {
288 entry:
289   %0 = icmp ule i32 %a, %b
290   %1 = sext i1 %0 to i32
291   store i32 %1, i32 addrspace(1)* %out
292   ret void
293 }
294
295 ; FUNC-LABEL: {{^}}i32_sgt:
296 ; R600: SETGT_INT
297 ; SI: v_cmp_gt_i32
298 define void @i32_sgt(i32 addrspace(1)* %out, i32 %a, i32 %b) {
299 entry:
300   %0 = icmp sgt i32 %a, %b
301   %1 = sext i1 %0 to i32
302   store i32 %1, i32 addrspace(1)* %out
303   ret void
304 }
305
306 ; FUNC-LABEL: {{^}}i32_sge:
307 ; R600: SETGE_INT
308 ; SI: v_cmp_ge_i32
309 define void @i32_sge(i32 addrspace(1)* %out, i32 %a, i32 %b) {
310 entry:
311   %0 = icmp sge i32 %a, %b
312   %1 = sext i1 %0 to i32
313   store i32 %1, i32 addrspace(1)* %out
314   ret void
315 }
316
317 ; FUNC-LABEL: {{^}}i32_slt:
318 ; R600: SETGT_INT
319 ; SI: v_cmp_lt_i32
320 define void @i32_slt(i32 addrspace(1)* %out, i32 %a, i32 %b) {
321 entry:
322   %0 = icmp slt i32 %a, %b
323   %1 = sext i1 %0 to i32
324   store i32 %1, i32 addrspace(1)* %out
325   ret void
326 }
327
328 ; FUNC-LABEL: {{^}}i32_sle:
329 ; R600: SETGE_INT
330 ; SI: v_cmp_le_i32
331 define void @i32_sle(i32 addrspace(1)* %out, i32 %a, i32 %b) {
332 entry:
333   %0 = icmp sle i32 %a, %b
334   %1 = sext i1 %0 to i32
335   store i32 %1, i32 addrspace(1)* %out
336   ret void
337 }
338
339 ; FIXME: This does 4 compares
340 ; FUNC-LABEL: {{^}}v3i32_eq:
341 ; SI-DAG: v_cmp_eq_i32
342 ; SI-DAG: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1,
343 ; SI-DAG: v_cmp_eq_i32
344 ; SI-DAG: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1,
345 ; SI-DAG: v_cmp_eq_i32
346 ; SI-DAG: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1,
347 ; SI: s_endpgm
348 define void @v3i32_eq(<3 x i32> addrspace(1)* %out, <3 x i32> addrspace(1)* %ptra, <3 x i32> addrspace(1)* %ptrb) {
349   %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
350   %gep.a = getelementptr <3 x i32> addrspace(1)* %ptra, i32 %tid
351   %gep.b = getelementptr <3 x i32> addrspace(1)* %ptrb, i32 %tid
352   %gep.out = getelementptr <3 x i32> addrspace(1)* %out, i32 %tid
353   %a = load <3 x i32> addrspace(1)* %gep.a
354   %b = load <3 x i32> addrspace(1)* %gep.b
355   %cmp = icmp eq <3 x i32> %a, %b
356   %ext = sext <3 x i1> %cmp to <3 x i32>
357   store <3 x i32> %ext, <3 x i32> addrspace(1)* %gep.out
358   ret void
359 }
360
361 ; FUNC-LABEL: {{^}}v3i8_eq:
362 ; SI-DAG: v_cmp_eq_i32
363 ; SI-DAG: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1,
364 ; SI-DAG: v_cmp_eq_i32
365 ; SI-DAG: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1,
366 ; SI-DAG: v_cmp_eq_i32
367 ; SI-DAG: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1,
368 ; SI: s_endpgm
369 define void @v3i8_eq(<3 x i8> addrspace(1)* %out, <3 x i8> addrspace(1)* %ptra, <3 x i8> addrspace(1)* %ptrb) {
370   %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
371   %gep.a = getelementptr <3 x i8> addrspace(1)* %ptra, i32 %tid
372   %gep.b = getelementptr <3 x i8> addrspace(1)* %ptrb, i32 %tid
373   %gep.out = getelementptr <3 x i8> addrspace(1)* %out, i32 %tid
374   %a = load <3 x i8> addrspace(1)* %gep.a
375   %b = load <3 x i8> addrspace(1)* %gep.b
376   %cmp = icmp eq <3 x i8> %a, %b
377   %ext = sext <3 x i1> %cmp to <3 x i8>
378   store <3 x i8> %ext, <3 x i8> addrspace(1)* %gep.out
379   ret void
380 }