1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -global-isel=0 -mtriple=amdgcn-- -mcpu=gfx950 < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX950,GFX950-SDAG %s
3 ; RUN: llc -global-isel -mtriple=amdgcn-- -mcpu=gfx950 < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX950,GFX950-GISEL %s
5 ; ========= Single bit functions =========
7 define amdgpu_ps float @not_and_not_and_not_and(i32 %a, i32 %b, i32 %c) {
8 ; GCN-LABEL: not_and_not_and_not_and:
10 ; GCN-NEXT: v_bitop3_b32 v0, v0, v1, v2 bitop3:1
11 ; GCN-NEXT: ; return to shader part epilog
12 %nota = xor i32 %a, -1
13 %notb = xor i32 %b, -1
14 %notc = xor i32 %c, -1
15 %and1 = and i32 %nota, %notc
16 %and2 = and i32 %and1, %notb
17 %ret_cast = bitcast i32 %and2 to float
21 define amdgpu_ps float @not_and_not_and_and(i32 %a, i32 %b, i32 %c) {
22 ; GCN-LABEL: not_and_not_and_and:
24 ; GCN-NEXT: v_bitop3_b32 v0, v0, v1, v2 bitop3:2
25 ; GCN-NEXT: ; return to shader part epilog
26 %nota = xor i32 %a, -1
27 %notb = xor i32 %b, -1
28 %and1 = and i32 %nota, %c
29 %and2 = and i32 %and1, %notb
30 %ret_cast = bitcast i32 %and2 to float
34 define amdgpu_ps float @not_and_and_not_and(i32 %a, i32 %b, i32 %c) {
35 ; GCN-LABEL: not_and_and_not_and:
37 ; GCN-NEXT: v_bitop3_b32 v0, v0, v1, v2 bitop3:4
38 ; GCN-NEXT: ; return to shader part epilog
39 %nota = xor i32 %a, -1
40 %notc = xor i32 %c, -1
41 %and1 = and i32 %nota, %notc
42 %and2 = and i32 %and1, %b
43 %ret_cast = bitcast i32 %and2 to float
47 define amdgpu_ps float @not_and_and_and(i32 %a, i32 %b, i32 %c) {
48 ; GFX950-SDAG-LABEL: not_and_and_and:
49 ; GFX950-SDAG: ; %bb.0:
50 ; GFX950-SDAG-NEXT: v_bitop3_b32 v0, v0, v1, v2 bitop3:8
51 ; GFX950-SDAG-NEXT: ; return to shader part epilog
53 ; GFX950-GISEL-LABEL: not_and_and_and:
54 ; GFX950-GISEL: ; %bb.0:
55 ; GFX950-GISEL-NEXT: v_bitop3_b32 v0, v0, v2, v0 bitop3:0xc
56 ; GFX950-GISEL-NEXT: v_and_b32_e32 v0, v0, v1
57 ; GFX950-GISEL-NEXT: ; return to shader part epilog
58 %nota = xor i32 %a, -1
59 %and1 = and i32 %nota, %c
60 %and2 = and i32 %and1, %b
61 %ret_cast = bitcast i32 %and2 to float
65 define amdgpu_ps float @and_not_and_not_and(i32 %a, i32 %b, i32 %c) {
66 ; GCN-LABEL: and_not_and_not_and:
68 ; GCN-NEXT: v_bitop3_b32 v0, v0, v1, v2 bitop3:0x10
69 ; GCN-NEXT: ; return to shader part epilog
70 %notb = xor i32 %b, -1
71 %notc = xor i32 %c, -1
72 %and1 = and i32 %a, %notc
73 %and2 = and i32 %and1, %notb
74 %ret_cast = bitcast i32 %and2 to float
78 define amdgpu_ps float @and_not_and_and(i32 %a, i32 %b, i32 %c) {
79 ; GFX950-SDAG-LABEL: and_not_and_and:
80 ; GFX950-SDAG: ; %bb.0:
81 ; GFX950-SDAG-NEXT: v_bitop3_b32 v0, v0, v1, v2 bitop3:0x20
82 ; GFX950-SDAG-NEXT: ; return to shader part epilog
84 ; GFX950-GISEL-LABEL: and_not_and_and:
85 ; GFX950-GISEL: ; %bb.0:
86 ; GFX950-GISEL-NEXT: v_not_b32_e32 v1, v1
87 ; GFX950-GISEL-NEXT: v_and_b32_e32 v0, v0, v2
88 ; GFX950-GISEL-NEXT: v_and_b32_e32 v0, v0, v1
89 ; GFX950-GISEL-NEXT: ; return to shader part epilog
90 %notb = xor i32 %b, -1
91 %and1 = and i32 %a, %c
92 %and2 = and i32 %and1, %notb
93 %ret_cast = bitcast i32 %and2 to float
97 define amdgpu_ps float @and_and_not_and(i32 %a, i32 %b, i32 %c) {
98 ; GFX950-SDAG-LABEL: and_and_not_and:
99 ; GFX950-SDAG: ; %bb.0:
100 ; GFX950-SDAG-NEXT: v_bitop3_b32 v0, v0, v1, v2 bitop3:0x40
101 ; GFX950-SDAG-NEXT: ; return to shader part epilog
103 ; GFX950-GISEL-LABEL: and_and_not_and:
104 ; GFX950-GISEL: ; %bb.0:
105 ; GFX950-GISEL-NEXT: v_bitop3_b32 v0, v0, v2, v0 bitop3:0x30
106 ; GFX950-GISEL-NEXT: v_and_b32_e32 v0, v0, v1
107 ; GFX950-GISEL-NEXT: ; return to shader part epilog
108 %notc = xor i32 %c, -1
109 %and1 = and i32 %a, %notc
110 %and2 = and i32 %and1, %b
111 %ret_cast = bitcast i32 %and2 to float
115 define amdgpu_ps float @and_and_and(i32 %a, i32 %b, i32 %c) {
116 ; GFX950-SDAG-LABEL: and_and_and:
117 ; GFX950-SDAG: ; %bb.0:
118 ; GFX950-SDAG-NEXT: v_bitop3_b32 v0, v0, v1, v2 bitop3:0x80
119 ; GFX950-SDAG-NEXT: ; return to shader part epilog
121 ; GFX950-GISEL-LABEL: and_and_and:
122 ; GFX950-GISEL: ; %bb.0:
123 ; GFX950-GISEL-NEXT: v_bitop3_b32 v0, v0, v1, v2 bitop3:0x80
124 ; GFX950-GISEL-NEXT: ; return to shader part epilog
125 %and1 = and i32 %a, %c
126 %and2 = and i32 %and1, %b
127 %ret_cast = bitcast i32 %and2 to float
131 ; ========= Multi bit functions =========
133 define amdgpu_ps float @test_12(i32 %a, i32 %b) {
134 ; GFX950-SDAG-LABEL: test_12:
135 ; GFX950-SDAG: ; %bb.0:
136 ; GFX950-SDAG-NEXT: v_bitop3_b32 v0, v0, v1, v0 bitop3:0xc
137 ; GFX950-SDAG-NEXT: ; return to shader part epilog
139 ; GFX950-GISEL-LABEL: test_12:
140 ; GFX950-GISEL: ; %bb.0:
141 ; GFX950-GISEL-NEXT: v_bitop3_b32 v0, v0, v1, v0 bitop3:0xc
142 ; GFX950-GISEL-NEXT: ; return to shader part epilog
143 %nota = xor i32 %a, -1
144 %and1 = and i32 %nota, %b
145 %ret_cast = bitcast i32 %and1 to float
149 define amdgpu_ps float @test_63(i32 %a, i32 %b) {
150 ; GFX950-SDAG-LABEL: test_63:
151 ; GFX950-SDAG: ; %bb.0:
152 ; GFX950-SDAG-NEXT: v_bitop3_b32 v0, v0, v1, v0 bitop3:0x3f
153 ; GFX950-SDAG-NEXT: ; return to shader part epilog
155 ; GFX950-GISEL-LABEL: test_63:
156 ; GFX950-GISEL: ; %bb.0:
157 ; GFX950-GISEL-NEXT: v_not_b32_e32 v0, v0
158 ; GFX950-GISEL-NEXT: v_not_b32_e32 v1, v1
159 ; GFX950-GISEL-NEXT: v_or_b32_e32 v0, v0, v1
160 ; GFX950-GISEL-NEXT: ; return to shader part epilog
161 %nota = xor i32 %a, -1
162 %notb = xor i32 %b, -1
163 %or = or i32 %nota, %notb
164 %ret_cast = bitcast i32 %or to float
168 define amdgpu_ps float @test_59(i32 %a, i32 %b, i32 %c) {
169 ; GCN-LABEL: test_59:
171 ; GCN-NEXT: v_bitop3_b32 v0, v0, v1, v2 bitop3:0x3b
172 ; GCN-NEXT: ; return to shader part epilog
173 %nota = xor i32 %a, -1
174 %notb = xor i32 %b, -1
175 %and1 = and i32 %nota, %c
176 %or = or i32 %and1, %notb
177 %ret_cast = bitcast i32 %or to float
181 define amdgpu_ps float @test_126(i32 %a, i32 %b, i32 %c) {
182 ; GFX950-SDAG-LABEL: test_126:
183 ; GFX950-SDAG: ; %bb.0:
184 ; GFX950-SDAG-NEXT: v_bitop3_b32 v0, v0, v2, v1 bitop3:0x7e
185 ; GFX950-SDAG-NEXT: ; return to shader part epilog
187 ; GFX950-GISEL-LABEL: test_126:
188 ; GFX950-GISEL: ; %bb.0:
189 ; GFX950-GISEL-NEXT: v_xor_b32_e32 v1, v0, v1
190 ; GFX950-GISEL-NEXT: v_xor_b32_e32 v0, v0, v2
191 ; GFX950-GISEL-NEXT: v_or_b32_e32 v0, v1, v0
192 ; GFX950-GISEL-NEXT: ; return to shader part epilog
193 %xor1 = xor i32 %a, %b
194 %xor2 = xor i32 %a, %c
195 %or = or i32 %xor1, %xor2
196 %ret_cast = bitcast i32 %or to float
200 ; Src vector exhausted during search but recovered using 'not' lookahead.
201 ; GlobalISel has slightly different input, so it does not happen.
203 ; FIXME: Improve global isel code.
205 define amdgpu_ps float @test_12_src_overflow(i32 %a, i32 %b, i32 %c) {
206 ; GFX950-SDAG-LABEL: test_12_src_overflow:
207 ; GFX950-SDAG: ; %bb.0:
208 ; GFX950-SDAG-NEXT: v_bitop3_b32 v0, v0, v1, v0 bitop3:0xc
209 ; GFX950-SDAG-NEXT: ; return to shader part epilog
211 ; GFX950-GISEL-LABEL: test_12_src_overflow:
212 ; GFX950-GISEL: ; %bb.0:
213 ; GFX950-GISEL-NEXT: v_not_b32_e32 v3, v0
214 ; GFX950-GISEL-NEXT: v_not_b32_e32 v4, v2
215 ; GFX950-GISEL-NEXT: v_bitop3_b32 v0, v0, v2, v0 bitop3:0xc
216 ; GFX950-GISEL-NEXT: v_and_b32_e32 v2, v3, v4
217 ; GFX950-GISEL-NEXT: v_bitop3_b32 v0, v0, v1, v2 bitop3:0xc8
218 ; GFX950-GISEL-NEXT: ; return to shader part epilog
219 %nota = xor i32 %a, -1
220 %notc = xor i32 %c, -1
221 %and1 = and i32 %nota, %c
222 %and2 = and i32 %and1, %b
223 %and3 = and i32 %nota, %notc
224 %and4 = and i32 %and3, %b
225 %or = or i32 %and2, %and4
226 %ret_cast = bitcast i32 %or to float
230 ; This could be a single LOP3 operation with tbl = 100, but Src vector exhausted during search.
232 define amdgpu_ps float @test_100_src_overflow(i32 %a, i32 %b, i32 %c) {
233 ; GFX950-SDAG-LABEL: test_100_src_overflow:
234 ; GFX950-SDAG: ; %bb.0:
235 ; GFX950-SDAG-NEXT: v_bitop3_b32 v3, v1, v2, v0 bitop3:0x10
236 ; GFX950-SDAG-NEXT: v_bitop3_b32 v4, v0, v2, v1 bitop3:0x40
237 ; GFX950-SDAG-NEXT: v_bitop3_b32 v0, v1, v2, v0 bitop3:0x20
238 ; GFX950-SDAG-NEXT: v_or3_b32 v0, v3, v4, v0
239 ; GFX950-SDAG-NEXT: ; return to shader part epilog
241 ; GFX950-GISEL-LABEL: test_100_src_overflow:
242 ; GFX950-GISEL: ; %bb.0:
243 ; GFX950-GISEL-NEXT: v_bitop3_b32 v3, v2, v0, v2 bitop3:3
244 ; GFX950-GISEL-NEXT: v_and_b32_e32 v3, v1, v3
245 ; GFX950-GISEL-NEXT: v_bitop3_b32 v4, v0, v1, v0 bitop3:0x30
246 ; GFX950-GISEL-NEXT: v_and_b32_e32 v0, v1, v0
247 ; GFX950-GISEL-NEXT: v_not_b32_e32 v1, v2
248 ; GFX950-GISEL-NEXT: v_and_b32_e32 v4, v4, v2
249 ; GFX950-GISEL-NEXT: v_and_b32_e32 v0, v0, v1
250 ; GFX950-GISEL-NEXT: v_or3_b32 v0, v3, v4, v0
251 ; GFX950-GISEL-NEXT: ; return to shader part epilog
253 %not1 = xor i32 %or1, -1
254 %and1 = and i32 %b, %not1
255 %not2 = xor i32 %b, -1
256 %and2 = and i32 %a, %not2
257 %and3 = and i32 %and2, %c
258 %and4 = and i32 %b, %a
259 %not3 = xor i32 %c, -1
260 %and5 = and i32 %and4, %not3
261 %or2 = or i32 %and1, %and3
262 %or3 = or i32 %or2, %and5
263 %ret_cast = bitcast i32 %or3 to float
267 ; ========= Ternary logical operations take precedence =========
269 define amdgpu_ps float @test_xor3(i32 %a, i32 %b, i32 %c) {
270 ; GCN-LABEL: test_xor3:
272 ; GCN-NEXT: v_xor_b32_e32 v0, v0, v1
273 ; GCN-NEXT: v_xor_b32_e32 v0, v0, v2
274 ; GCN-NEXT: ; return to shader part epilog
275 %xor1 = xor i32 %a, %b
276 %xor2 = xor i32 %xor1, %c
277 %ret_cast = bitcast i32 %xor2 to float
281 define amdgpu_ps float @test_or3(i32 %a, i32 %b, i32 %c) {
282 ; GCN-LABEL: test_or3:
284 ; GCN-NEXT: v_or3_b32 v0, v0, v1, v2
285 ; GCN-NEXT: ; return to shader part epilog
287 %or2 = or i32 %or1, %c
288 %ret_cast = bitcast i32 %or2 to float
292 define amdgpu_ps float @test_and_or(i32 %a, i32 %b, i32 %c) {
293 ; GCN-LABEL: test_and_or:
295 ; GCN-NEXT: v_and_or_b32 v0, v0, v1, v2
296 ; GCN-NEXT: ; return to shader part epilog
297 %and1 = and i32 %a, %b
298 %or1 = or i32 %and1, %c
299 %ret_cast = bitcast i32 %or1 to float
303 ; ========= Uniform cases =========
305 define amdgpu_ps float @uniform_3_op(i32 inreg %a, i32 inreg %b, i32 inreg %c) {
306 ; GCN-LABEL: uniform_3_op:
308 ; GCN-NEXT: s_andn2_b32 s0, s2, s0
309 ; GCN-NEXT: s_and_b32 s0, s0, s1
310 ; GCN-NEXT: v_mov_b32_e32 v0, s0
311 ; GCN-NEXT: ; return to shader part epilog
312 %nota = xor i32 %a, -1
313 %and1 = and i32 %nota, %c
314 %and2 = and i32 %and1, %b
315 %ret_cast = bitcast i32 %and2 to float
319 define amdgpu_ps float @uniform_4_op(i32 inreg %a, i32 inreg %b, i32 inreg %c) {
320 ; GFX950-SDAG-LABEL: uniform_4_op:
321 ; GFX950-SDAG: ; %bb.0:
322 ; GFX950-SDAG-NEXT: v_mov_b32_e32 v0, s1
323 ; GFX950-SDAG-NEXT: v_mov_b32_e32 v1, s2
324 ; GFX950-SDAG-NEXT: v_bitop3_b32 v0, s0, v0, v1 bitop3:2
325 ; GFX950-SDAG-NEXT: ; return to shader part epilog
327 ; GFX950-GISEL-LABEL: uniform_4_op:
328 ; GFX950-GISEL: ; %bb.0:
329 ; GFX950-GISEL-NEXT: s_andn2_b32 s0, s2, s0
330 ; GFX950-GISEL-NEXT: s_andn2_b32 s0, s0, s1
331 ; GFX950-GISEL-NEXT: v_mov_b32_e32 v0, s0
332 ; GFX950-GISEL-NEXT: ; return to shader part epilog
333 %nota = xor i32 %a, -1
334 %notb = xor i32 %b, -1
335 %and1 = and i32 %nota, %c
336 %and2 = and i32 %and1, %notb
337 %ret_cast = bitcast i32 %and2 to float
341 ; ========= 16 bit tests =========
343 define amdgpu_ps half @not_and_not_and_not_and_b16(i16 %a, i16 %b, i16 %c) {
344 ; GCN-LABEL: not_and_not_and_not_and_b16:
346 ; GCN-NEXT: v_bitop3_b16 v0, v0, v1, v2 bitop3:1
347 ; GCN-NEXT: ; return to shader part epilog
348 %nota = xor i16 %a, -1
349 %notb = xor i16 %b, -1
350 %notc = xor i16 %c, -1
351 %and1 = and i16 %nota, %notc
352 %and2 = and i16 %and1, %notb
353 %ret_cast = bitcast i16 %and2 to half
357 define amdgpu_ps half @not_and_not_and_and_b16(i16 %a, i16 %b, i16 %c) {
358 ; GCN-LABEL: not_and_not_and_and_b16:
360 ; GCN-NEXT: v_bitop3_b16 v0, v0, v1, v2 bitop3:2
361 ; GCN-NEXT: ; return to shader part epilog
362 %nota = xor i16 %a, -1
363 %notb = xor i16 %b, -1
364 %and1 = and i16 %nota, %c
365 %and2 = and i16 %and1, %notb
366 %ret_cast = bitcast i16 %and2 to half
370 define amdgpu_ps half @not_and_and_not_and_b16(i16 %a, i16 %b, i16 %c) {
371 ; GCN-LABEL: not_and_and_not_and_b16:
373 ; GCN-NEXT: v_bitop3_b16 v0, v0, v1, v2 bitop3:4
374 ; GCN-NEXT: ; return to shader part epilog
375 %nota = xor i16 %a, -1
376 %notc = xor i16 %c, -1
377 %and1 = and i16 %nota, %notc
378 %and2 = and i16 %and1, %b
379 %ret_cast = bitcast i16 %and2 to half
383 define amdgpu_ps half @test_xor3_b16(i16 %a, i16 %b, i16 %c) {
384 ; GFX950-SDAG-LABEL: test_xor3_b16:
385 ; GFX950-SDAG: ; %bb.0:
386 ; GFX950-SDAG-NEXT: v_bitop3_b16 v0, v0, v2, v1 bitop3:0x96
387 ; GFX950-SDAG-NEXT: ; return to shader part epilog
389 ; GFX950-GISEL-LABEL: test_xor3_b16:
390 ; GFX950-GISEL: ; %bb.0:
391 ; GFX950-GISEL-NEXT: v_xor_b32_e32 v0, v0, v1
392 ; GFX950-GISEL-NEXT: v_xor_b32_e32 v0, v0, v2
393 ; GFX950-GISEL-NEXT: ; return to shader part epilog
394 %xor1 = xor i16 %a, %b
395 %xor2 = xor i16 %xor1, %c
396 %ret_cast = bitcast i16 %xor2 to half
400 define amdgpu_ps half @test_or3_b16(i16 %a, i16 %b, i16 %c) {
401 ; GFX950-SDAG-LABEL: test_or3_b16:
402 ; GFX950-SDAG: ; %bb.0:
403 ; GFX950-SDAG-NEXT: v_bitop3_b16 v0, v0, v2, v1 bitop3:0xfe
404 ; GFX950-SDAG-NEXT: ; return to shader part epilog
406 ; GFX950-GISEL-LABEL: test_or3_b16:
407 ; GFX950-GISEL: ; %bb.0:
408 ; GFX950-GISEL-NEXT: v_or3_b32 v0, v0, v1, v2
409 ; GFX950-GISEL-NEXT: ; return to shader part epilog
411 %or2 = or i16 %or1, %c
412 %ret_cast = bitcast i16 %or2 to half
416 define amdgpu_ps half @test_and_or_b16(i16 %a, i16 %b, i16 %c) {
417 ; GFX950-SDAG-LABEL: test_and_or_b16:
418 ; GFX950-SDAG: ; %bb.0:
419 ; GFX950-SDAG-NEXT: v_bitop3_b16 v0, v0, v2, v1 bitop3:0xec
420 ; GFX950-SDAG-NEXT: ; return to shader part epilog
422 ; GFX950-GISEL-LABEL: test_and_or_b16:
423 ; GFX950-GISEL: ; %bb.0:
424 ; GFX950-GISEL-NEXT: v_and_or_b32 v0, v0, v1, v2
425 ; GFX950-GISEL-NEXT: ; return to shader part epilog
426 %and1 = and i16 %a, %b
427 %or1 = or i16 %and1, %c
428 %ret_cast = bitcast i16 %or1 to half
431 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: