1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -march=amdgcn -verify-machineinstrs | FileCheck %s -enable-var-scope --check-prefix=SI
3; RUN: llc < %s -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs | FileCheck %s -enable-var-scope --check-prefix=VI
4; RUN: llc < %s -march=r600 -mcpu=cypress -verify-machineinstrs | FileCheck %s -enable-var-scope --check-prefix=EG
5; RUN: llc < %s -march=amdgcn -mcpu=gfx1010 -verify-machineinstrs | FileCheck %s -enable-var-scope --check-prefix=GFX10
6; RUN: llc < %s -global-isel -march=amdgcn -mcpu=gfx1010 -verify-machineinstrs | FileCheck %s -enable-var-scope --check-prefix=GFX10-GISEL
7
8declare i7 @llvm.cttz.i7(i7, i1) nounwind readnone
9declare i8 @llvm.cttz.i8(i8, i1) nounwind readnone
10declare i16 @llvm.cttz.i16(i16, i1) nounwind readnone
11
12declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone
13declare <2 x i32> @llvm.cttz.v2i32(<2 x i32>, i1) nounwind readnone
14declare <4 x i32> @llvm.cttz.v4i32(<4 x i32>, i1) nounwind readnone
15
16declare i64 @llvm.cttz.i64(i64, i1) nounwind readnone
17declare <2 x i64> @llvm.cttz.v2i64(<2 x i64>, i1) nounwind readnone
18declare <4 x i64> @llvm.cttz.v4i64(<4 x i64>, i1) nounwind readnone
19
20declare i32 @llvm.amdgcn.workitem.id.x() nounwind readnone
21
22define amdgpu_kernel void @s_cttz_i32(i32 addrspace(1)* noalias %out, i32 %val) nounwind {
23; SI-LABEL: s_cttz_i32:
24; SI:       ; %bb.0:
25; SI-NEXT:    s_load_dword s2, s[0:1], 0xb
26; SI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
27; SI-NEXT:    s_mov_b32 s3, 0xf000
28; SI-NEXT:    s_waitcnt lgkmcnt(0)
29; SI-NEXT:    s_ff1_i32_b32 s2, s2
30; SI-NEXT:    s_min_u32 s4, s2, 32
31; SI-NEXT:    s_mov_b32 s2, -1
32; SI-NEXT:    v_mov_b32_e32 v0, s4
33; SI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
34; SI-NEXT:    s_endpgm
35;
36; VI-LABEL: s_cttz_i32:
37; VI:       ; %bb.0:
38; VI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
39; VI-NEXT:    s_load_dword s0, s[0:1], 0x2c
40; VI-NEXT:    s_mov_b32 s7, 0xf000
41; VI-NEXT:    s_mov_b32 s6, -1
42; VI-NEXT:    s_waitcnt lgkmcnt(0)
43; VI-NEXT:    s_ff1_i32_b32 s0, s0
44; VI-NEXT:    s_min_u32 s0, s0, 32
45; VI-NEXT:    v_mov_b32_e32 v0, s0
46; VI-NEXT:    buffer_store_dword v0, off, s[4:7], 0
47; VI-NEXT:    s_endpgm
48;
49; EG-LABEL: s_cttz_i32:
50; EG:       ; %bb.0:
51; EG-NEXT:    ALU 3, @4, KC0[CB0:0-32], KC1[]
52; EG-NEXT:    MEM_RAT_CACHELESS STORE_RAW T0.X, T1.X, 1
53; EG-NEXT:    CF_END
54; EG-NEXT:    PAD
55; EG-NEXT:    ALU clause starting at 4:
56; EG-NEXT:     FFBL_INT * T0.W, KC0[2].Z,
57; EG-NEXT:     CNDE_INT T0.X, KC0[2].Z, literal.x, PV.W,
58; EG-NEXT:     LSHR * T1.X, KC0[2].Y, literal.y,
59; EG-NEXT:    32(4.484155e-44), 2(2.802597e-45)
60;
61; GFX10-LABEL: s_cttz_i32:
62; GFX10:       ; %bb.0:
63; GFX10-NEXT:    s_clause 0x1
64; GFX10-NEXT:    s_load_dword s4, s[0:1], 0x2c
65; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x24
66; GFX10-NEXT:    v_mov_b32_e32 v0, 0
67; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
68; GFX10-NEXT:    s_ff1_i32_b32 s0, s4
69; GFX10-NEXT:    s_min_u32 s0, s0, 32
70; GFX10-NEXT:    v_mov_b32_e32 v1, s0
71; GFX10-NEXT:    global_store_dword v0, v1, s[2:3]
72; GFX10-NEXT:    s_endpgm
73;
74; GFX10-GISEL-LABEL: s_cttz_i32:
75; GFX10-GISEL:       ; %bb.0:
76; GFX10-GISEL-NEXT:    s_clause 0x1
77; GFX10-GISEL-NEXT:    s_load_dword s4, s[0:1], 0x2c
78; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x24
79; GFX10-GISEL-NEXT:    v_mov_b32_e32 v1, 0
80; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
81; GFX10-GISEL-NEXT:    s_ff1_i32_b32 s0, s4
82; GFX10-GISEL-NEXT:    s_cmp_eq_u32 s4, 0
83; GFX10-GISEL-NEXT:    s_cselect_b32 s0, 32, s0
84; GFX10-GISEL-NEXT:    v_mov_b32_e32 v0, s0
85; GFX10-GISEL-NEXT:    global_store_dword v1, v0, s[2:3]
86; GFX10-GISEL-NEXT:    s_endpgm
87  %cttz = call i32 @llvm.cttz.i32(i32 %val, i1 false) nounwind readnone
88  store i32 %cttz, i32 addrspace(1)* %out, align 4
89  ret void
90}
91
92define amdgpu_kernel void @v_cttz_i32(i32 addrspace(1)* noalias %out, i32 addrspace(1)* noalias %valptr) nounwind {
93; SI-LABEL: v_cttz_i32:
94; SI:       ; %bb.0:
95; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
96; SI-NEXT:    s_mov_b32 s3, 0xf000
97; SI-NEXT:    s_mov_b32 s6, 0
98; SI-NEXT:    s_mov_b32 s7, s3
99; SI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
100; SI-NEXT:    v_mov_b32_e32 v1, 0
101; SI-NEXT:    s_waitcnt lgkmcnt(0)
102; SI-NEXT:    buffer_load_dword v0, v[0:1], s[4:7], 0 addr64
103; SI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
104; SI-NEXT:    s_mov_b32 s2, -1
105; SI-NEXT:    s_waitcnt vmcnt(0)
106; SI-NEXT:    v_ffbl_b32_e32 v0, v0
107; SI-NEXT:    v_min_u32_e32 v0, 32, v0
108; SI-NEXT:    s_waitcnt lgkmcnt(0)
109; SI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
110; SI-NEXT:    s_endpgm
111;
112; VI-LABEL: v_cttz_i32:
113; VI:       ; %bb.0:
114; VI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
115; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x2c
116; VI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
117; VI-NEXT:    s_mov_b32 s7, 0xf000
118; VI-NEXT:    s_mov_b32 s6, -1
119; VI-NEXT:    s_waitcnt lgkmcnt(0)
120; VI-NEXT:    v_mov_b32_e32 v1, s1
121; VI-NEXT:    v_add_u32_e32 v0, vcc, s0, v0
122; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
123; VI-NEXT:    flat_load_dword v0, v[0:1]
124; VI-NEXT:    s_waitcnt vmcnt(0)
125; VI-NEXT:    v_ffbl_b32_e32 v0, v0
126; VI-NEXT:    v_min_u32_e32 v0, 32, v0
127; VI-NEXT:    buffer_store_dword v0, off, s[4:7], 0
128; VI-NEXT:    s_endpgm
129;
130; EG-LABEL: v_cttz_i32:
131; EG:       ; %bb.0:
132; EG-NEXT:    ALU 2, @8, KC0[CB0:0-32], KC1[]
133; EG-NEXT:    TEX 0 @6
134; EG-NEXT:    ALU 3, @11, KC0[CB0:0-32], KC1[]
135; EG-NEXT:    MEM_RAT_CACHELESS STORE_RAW T0.X, T1.X, 1
136; EG-NEXT:    CF_END
137; EG-NEXT:    PAD
138; EG-NEXT:    Fetch clause starting at 6:
139; EG-NEXT:     VTX_READ_32 T0.X, T0.X, 0, #1
140; EG-NEXT:    ALU clause starting at 8:
141; EG-NEXT:     LSHL * T0.W, T0.X, literal.x,
142; EG-NEXT:    2(2.802597e-45), 0(0.000000e+00)
143; EG-NEXT:     ADD_INT * T0.X, KC0[2].Z, PV.W,
144; EG-NEXT:    ALU clause starting at 11:
145; EG-NEXT:     FFBL_INT * T0.W, T0.X,
146; EG-NEXT:     CNDE_INT T0.X, T0.X, literal.x, PV.W,
147; EG-NEXT:     LSHR * T1.X, KC0[2].Y, literal.y,
148; EG-NEXT:    32(4.484155e-44), 2(2.802597e-45)
149;
150; GFX10-LABEL: v_cttz_i32:
151; GFX10:       ; %bb.0:
152; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
153; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
154; GFX10-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
155; GFX10-NEXT:    v_mov_b32_e32 v1, 0
156; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
157; GFX10-NEXT:    global_load_dword v0, v0, s[2:3]
158; GFX10-NEXT:    s_waitcnt vmcnt(0)
159; GFX10-NEXT:    v_ffbl_b32_e32 v0, v0
160; GFX10-NEXT:    v_min_u32_e32 v0, 32, v0
161; GFX10-NEXT:    global_store_dword v1, v0, s[0:1]
162; GFX10-NEXT:    s_endpgm
163;
164; GFX10-GISEL-LABEL: v_cttz_i32:
165; GFX10-GISEL:       ; %bb.0:
166; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
167; GFX10-GISEL-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
168; GFX10-GISEL-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
169; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
170; GFX10-GISEL-NEXT:    global_load_dword v0, v0, s[2:3]
171; GFX10-GISEL-NEXT:    s_waitcnt vmcnt(0)
172; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v1, v0
173; GFX10-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
174; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v0, v1, 32, vcc_lo
175; GFX10-GISEL-NEXT:    v_mov_b32_e32 v1, 0
176; GFX10-GISEL-NEXT:    global_store_dword v1, v0, s[0:1]
177; GFX10-GISEL-NEXT:    s_endpgm
178  %tid = call i32 @llvm.amdgcn.workitem.id.x()
179  %in.gep = getelementptr i32, i32 addrspace(1)* %valptr, i32 %tid
180  %val = load i32, i32 addrspace(1)* %in.gep, align 4
181  %cttz = call i32 @llvm.cttz.i32(i32 %val, i1 false) nounwind readnone
182  store i32 %cttz, i32 addrspace(1)* %out, align 4
183  ret void
184}
185
186define amdgpu_kernel void @v_cttz_v2i32(<2 x i32> addrspace(1)* noalias %out, <2 x i32> addrspace(1)* noalias %valptr) nounwind {
187; SI-LABEL: v_cttz_v2i32:
188; SI:       ; %bb.0:
189; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
190; SI-NEXT:    s_mov_b32 s3, 0xf000
191; SI-NEXT:    s_mov_b32 s6, 0
192; SI-NEXT:    v_lshlrev_b32_e32 v0, 3, v0
193; SI-NEXT:    v_mov_b32_e32 v1, 0
194; SI-NEXT:    s_mov_b32 s7, s3
195; SI-NEXT:    s_waitcnt lgkmcnt(0)
196; SI-NEXT:    buffer_load_dwordx2 v[0:1], v[0:1], s[4:7], 0 addr64
197; SI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
198; SI-NEXT:    s_mov_b32 s2, -1
199; SI-NEXT:    s_waitcnt vmcnt(0)
200; SI-NEXT:    v_ffbl_b32_e32 v1, v1
201; SI-NEXT:    v_ffbl_b32_e32 v0, v0
202; SI-NEXT:    v_min_u32_e32 v1, 32, v1
203; SI-NEXT:    v_min_u32_e32 v0, 32, v0
204; SI-NEXT:    s_waitcnt lgkmcnt(0)
205; SI-NEXT:    buffer_store_dwordx2 v[0:1], off, s[0:3], 0
206; SI-NEXT:    s_endpgm
207;
208; VI-LABEL: v_cttz_v2i32:
209; VI:       ; %bb.0:
210; VI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
211; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x2c
212; VI-NEXT:    v_lshlrev_b32_e32 v0, 3, v0
213; VI-NEXT:    s_mov_b32 s7, 0xf000
214; VI-NEXT:    s_mov_b32 s6, -1
215; VI-NEXT:    s_waitcnt lgkmcnt(0)
216; VI-NEXT:    v_mov_b32_e32 v1, s1
217; VI-NEXT:    v_add_u32_e32 v0, vcc, s0, v0
218; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
219; VI-NEXT:    flat_load_dwordx2 v[0:1], v[0:1]
220; VI-NEXT:    s_waitcnt vmcnt(0)
221; VI-NEXT:    v_ffbl_b32_e32 v1, v1
222; VI-NEXT:    v_ffbl_b32_e32 v0, v0
223; VI-NEXT:    v_min_u32_e32 v1, 32, v1
224; VI-NEXT:    v_min_u32_e32 v0, 32, v0
225; VI-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
226; VI-NEXT:    s_endpgm
227;
228; EG-LABEL: v_cttz_v2i32:
229; EG:       ; %bb.0:
230; EG-NEXT:    ALU 2, @8, KC0[CB0:0-32], KC1[]
231; EG-NEXT:    TEX 0 @6
232; EG-NEXT:    ALU 6, @11, KC0[CB0:0-32], KC1[]
233; EG-NEXT:    MEM_RAT_CACHELESS STORE_RAW T0.XY, T1.X, 1
234; EG-NEXT:    CF_END
235; EG-NEXT:    PAD
236; EG-NEXT:    Fetch clause starting at 6:
237; EG-NEXT:     VTX_READ_64 T0.XY, T0.X, 0, #1
238; EG-NEXT:    ALU clause starting at 8:
239; EG-NEXT:     LSHL * T0.W, T0.X, literal.x,
240; EG-NEXT:    3(4.203895e-45), 0(0.000000e+00)
241; EG-NEXT:     ADD_INT * T0.X, KC0[2].Z, PV.W,
242; EG-NEXT:    ALU clause starting at 11:
243; EG-NEXT:     FFBL_INT * T0.W, T0.Y,
244; EG-NEXT:     CNDE_INT T0.Y, T0.Y, literal.x, PV.W,
245; EG-NEXT:     FFBL_INT * T0.W, T0.X,
246; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
247; EG-NEXT:     CNDE_INT T0.X, T0.X, literal.x, PV.W,
248; EG-NEXT:     LSHR * T1.X, KC0[2].Y, literal.y,
249; EG-NEXT:    32(4.484155e-44), 2(2.802597e-45)
250;
251; GFX10-LABEL: v_cttz_v2i32:
252; GFX10:       ; %bb.0:
253; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
254; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 3, v0
255; GFX10-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
256; GFX10-NEXT:    v_mov_b32_e32 v2, 0
257; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
258; GFX10-NEXT:    global_load_dwordx2 v[0:1], v0, s[2:3]
259; GFX10-NEXT:    s_waitcnt vmcnt(0)
260; GFX10-NEXT:    v_ffbl_b32_e32 v1, v1
261; GFX10-NEXT:    v_ffbl_b32_e32 v0, v0
262; GFX10-NEXT:    v_min_u32_e32 v1, 32, v1
263; GFX10-NEXT:    v_min_u32_e32 v0, 32, v0
264; GFX10-NEXT:    global_store_dwordx2 v2, v[0:1], s[0:1]
265; GFX10-NEXT:    s_endpgm
266;
267; GFX10-GISEL-LABEL: v_cttz_v2i32:
268; GFX10-GISEL:       ; %bb.0:
269; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
270; GFX10-GISEL-NEXT:    v_lshlrev_b32_e32 v0, 3, v0
271; GFX10-GISEL-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
272; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
273; GFX10-GISEL-NEXT:    global_load_dwordx2 v[0:1], v0, s[2:3]
274; GFX10-GISEL-NEXT:    s_waitcnt vmcnt(0)
275; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v2, v0
276; GFX10-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
277; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v3, v1
278; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v0, v2, 32, vcc_lo
279; GFX10-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v1
280; GFX10-GISEL-NEXT:    v_mov_b32_e32 v2, 0
281; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v1, v3, 32, vcc_lo
282; GFX10-GISEL-NEXT:    global_store_dwordx2 v2, v[0:1], s[0:1]
283; GFX10-GISEL-NEXT:    s_endpgm
284  %tid = call i32 @llvm.amdgcn.workitem.id.x()
285  %in.gep = getelementptr <2 x i32>, <2 x i32> addrspace(1)* %valptr, i32 %tid
286  %val = load <2 x i32>, <2 x i32> addrspace(1)* %in.gep, align 8
287  %cttz = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %val, i1 false) nounwind readnone
288  store <2 x i32> %cttz, <2 x i32> addrspace(1)* %out, align 8
289  ret void
290}
291
292define amdgpu_kernel void @v_cttz_v4i32(<4 x i32> addrspace(1)* noalias %out, <4 x i32> addrspace(1)* noalias %valptr) nounwind {
293; SI-LABEL: v_cttz_v4i32:
294; SI:       ; %bb.0:
295; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
296; SI-NEXT:    s_mov_b32 s3, 0xf000
297; SI-NEXT:    s_mov_b32 s6, 0
298; SI-NEXT:    v_lshlrev_b32_e32 v0, 4, v0
299; SI-NEXT:    v_mov_b32_e32 v1, 0
300; SI-NEXT:    s_mov_b32 s7, s3
301; SI-NEXT:    s_waitcnt lgkmcnt(0)
302; SI-NEXT:    buffer_load_dwordx4 v[0:3], v[0:1], s[4:7], 0 addr64
303; SI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
304; SI-NEXT:    s_mov_b32 s2, -1
305; SI-NEXT:    s_waitcnt vmcnt(0)
306; SI-NEXT:    v_ffbl_b32_e32 v3, v3
307; SI-NEXT:    v_ffbl_b32_e32 v2, v2
308; SI-NEXT:    v_ffbl_b32_e32 v1, v1
309; SI-NEXT:    v_ffbl_b32_e32 v0, v0
310; SI-NEXT:    v_min_u32_e32 v3, 32, v3
311; SI-NEXT:    v_min_u32_e32 v2, 32, v2
312; SI-NEXT:    v_min_u32_e32 v1, 32, v1
313; SI-NEXT:    v_min_u32_e32 v0, 32, v0
314; SI-NEXT:    s_waitcnt lgkmcnt(0)
315; SI-NEXT:    buffer_store_dwordx4 v[0:3], off, s[0:3], 0
316; SI-NEXT:    s_endpgm
317;
318; VI-LABEL: v_cttz_v4i32:
319; VI:       ; %bb.0:
320; VI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
321; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x2c
322; VI-NEXT:    v_lshlrev_b32_e32 v0, 4, v0
323; VI-NEXT:    s_mov_b32 s7, 0xf000
324; VI-NEXT:    s_mov_b32 s6, -1
325; VI-NEXT:    s_waitcnt lgkmcnt(0)
326; VI-NEXT:    v_mov_b32_e32 v1, s1
327; VI-NEXT:    v_add_u32_e32 v0, vcc, s0, v0
328; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
329; VI-NEXT:    flat_load_dwordx4 v[0:3], v[0:1]
330; VI-NEXT:    s_waitcnt vmcnt(0)
331; VI-NEXT:    v_ffbl_b32_e32 v3, v3
332; VI-NEXT:    v_ffbl_b32_e32 v2, v2
333; VI-NEXT:    v_ffbl_b32_e32 v1, v1
334; VI-NEXT:    v_ffbl_b32_e32 v0, v0
335; VI-NEXT:    v_min_u32_e32 v3, 32, v3
336; VI-NEXT:    v_min_u32_e32 v2, 32, v2
337; VI-NEXT:    v_min_u32_e32 v1, 32, v1
338; VI-NEXT:    v_min_u32_e32 v0, 32, v0
339; VI-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
340; VI-NEXT:    s_endpgm
341;
342; EG-LABEL: v_cttz_v4i32:
343; EG:       ; %bb.0:
344; EG-NEXT:    ALU 2, @8, KC0[CB0:0-32], KC1[]
345; EG-NEXT:    TEX 0 @6
346; EG-NEXT:    ALU 12, @11, KC0[CB0:0-32], KC1[]
347; EG-NEXT:    MEM_RAT_CACHELESS STORE_RAW T0.XYZW, T1.X, 1
348; EG-NEXT:    CF_END
349; EG-NEXT:    PAD
350; EG-NEXT:    Fetch clause starting at 6:
351; EG-NEXT:     VTX_READ_128 T0.XYZW, T0.X, 0, #1
352; EG-NEXT:    ALU clause starting at 8:
353; EG-NEXT:     LSHL * T0.W, T0.X, literal.x,
354; EG-NEXT:    4(5.605194e-45), 0(0.000000e+00)
355; EG-NEXT:     ADD_INT * T0.X, KC0[2].Z, PV.W,
356; EG-NEXT:    ALU clause starting at 11:
357; EG-NEXT:     FFBL_INT * T1.W, T0.W,
358; EG-NEXT:     FFBL_INT T2.W, T0.Z,
359; EG-NEXT:     CNDE_INT * T0.W, T0.W, literal.x, PV.W, BS:VEC_021/SCL_122
360; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
361; EG-NEXT:     CNDE_INT T0.Z, T0.Z, literal.x, PV.W,
362; EG-NEXT:     FFBL_INT * T1.W, T0.Y,
363; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
364; EG-NEXT:     CNDE_INT T0.Y, T0.Y, literal.x, PV.W,
365; EG-NEXT:     FFBL_INT * T1.W, T0.X,
366; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
367; EG-NEXT:     CNDE_INT T0.X, T0.X, literal.x, PV.W,
368; EG-NEXT:     LSHR * T1.X, KC0[2].Y, literal.y,
369; EG-NEXT:    32(4.484155e-44), 2(2.802597e-45)
370;
371; GFX10-LABEL: v_cttz_v4i32:
372; GFX10:       ; %bb.0:
373; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
374; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 4, v0
375; GFX10-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
376; GFX10-NEXT:    v_mov_b32_e32 v4, 0
377; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
378; GFX10-NEXT:    global_load_dwordx4 v[0:3], v0, s[2:3]
379; GFX10-NEXT:    s_waitcnt vmcnt(0)
380; GFX10-NEXT:    v_ffbl_b32_e32 v3, v3
381; GFX10-NEXT:    v_ffbl_b32_e32 v2, v2
382; GFX10-NEXT:    v_ffbl_b32_e32 v1, v1
383; GFX10-NEXT:    v_ffbl_b32_e32 v0, v0
384; GFX10-NEXT:    v_min_u32_e32 v3, 32, v3
385; GFX10-NEXT:    v_min_u32_e32 v2, 32, v2
386; GFX10-NEXT:    v_min_u32_e32 v1, 32, v1
387; GFX10-NEXT:    v_min_u32_e32 v0, 32, v0
388; GFX10-NEXT:    global_store_dwordx4 v4, v[0:3], s[0:1]
389; GFX10-NEXT:    s_endpgm
390;
391; GFX10-GISEL-LABEL: v_cttz_v4i32:
392; GFX10-GISEL:       ; %bb.0:
393; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
394; GFX10-GISEL-NEXT:    v_lshlrev_b32_e32 v0, 4, v0
395; GFX10-GISEL-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
396; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
397; GFX10-GISEL-NEXT:    global_load_dwordx4 v[0:3], v0, s[2:3]
398; GFX10-GISEL-NEXT:    s_waitcnt vmcnt(0)
399; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v4, v0
400; GFX10-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
401; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v5, v1
402; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v6, v2
403; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v7, v3
404; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v0, v4, 32, vcc_lo
405; GFX10-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v1
406; GFX10-GISEL-NEXT:    v_mov_b32_e32 v4, 0
407; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v1, v5, 32, vcc_lo
408; GFX10-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v2
409; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v2, v6, 32, vcc_lo
410; GFX10-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v3
411; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v3, v7, 32, vcc_lo
412; GFX10-GISEL-NEXT:    global_store_dwordx4 v4, v[0:3], s[0:1]
413; GFX10-GISEL-NEXT:    s_endpgm
414  %tid = call i32 @llvm.amdgcn.workitem.id.x()
415  %in.gep = getelementptr <4 x i32>, <4 x i32> addrspace(1)* %valptr, i32 %tid
416  %val = load <4 x i32>, <4 x i32> addrspace(1)* %in.gep, align 16
417  %cttz = call <4 x i32> @llvm.cttz.v4i32(<4 x i32> %val, i1 false) nounwind readnone
418  store <4 x i32> %cttz, <4 x i32> addrspace(1)* %out, align 16
419  ret void
420}
421
422define amdgpu_kernel void @v_cttz_i8(i8 addrspace(1)* noalias %out, i8 addrspace(1)* noalias %valptr) nounwind {
423; SI-LABEL: v_cttz_i8:
424; SI:       ; %bb.0:
425; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
426; SI-NEXT:    s_mov_b32 s3, 0xf000
427; SI-NEXT:    s_mov_b32 s2, -1
428; SI-NEXT:    s_mov_b32 s6, s2
429; SI-NEXT:    s_mov_b32 s7, s3
430; SI-NEXT:    s_waitcnt lgkmcnt(0)
431; SI-NEXT:    buffer_load_ubyte v0, off, s[4:7], 0
432; SI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
433; SI-NEXT:    s_waitcnt vmcnt(0)
434; SI-NEXT:    v_or_b32_e32 v0, 0x100, v0
435; SI-NEXT:    v_ffbl_b32_e32 v0, v0
436; SI-NEXT:    s_waitcnt lgkmcnt(0)
437; SI-NEXT:    buffer_store_byte v0, off, s[0:3], 0
438; SI-NEXT:    s_endpgm
439;
440; VI-LABEL: v_cttz_i8:
441; VI:       ; %bb.0:
442; VI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
443; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x2c
444; VI-NEXT:    s_mov_b32 s7, 0xf000
445; VI-NEXT:    s_mov_b32 s6, -1
446; VI-NEXT:    s_mov_b32 s2, s6
447; VI-NEXT:    s_mov_b32 s3, s7
448; VI-NEXT:    s_waitcnt lgkmcnt(0)
449; VI-NEXT:    buffer_load_ubyte v0, off, s[0:3], 0
450; VI-NEXT:    s_waitcnt vmcnt(0)
451; VI-NEXT:    v_or_b32_e32 v0, 0x100, v0
452; VI-NEXT:    v_ffbl_b32_e32 v0, v0
453; VI-NEXT:    buffer_store_byte v0, off, s[4:7], 0
454; VI-NEXT:    s_endpgm
455;
456; EG-LABEL: v_cttz_i8:
457; EG:       ; %bb.0:
458; EG-NEXT:    ALU 0, @8, KC0[CB0:0-32], KC1[]
459; EG-NEXT:    TEX 0 @6
460; EG-NEXT:    ALU 14, @9, KC0[CB0:0-32], KC1[]
461; EG-NEXT:    MEM_RAT MSKOR T0.XW, T1.X
462; EG-NEXT:    CF_END
463; EG-NEXT:    PAD
464; EG-NEXT:    Fetch clause starting at 6:
465; EG-NEXT:     VTX_READ_8 T0.X, T0.X, 0, #1
466; EG-NEXT:    ALU clause starting at 8:
467; EG-NEXT:     MOV * T0.X, KC0[2].Z,
468; EG-NEXT:    ALU clause starting at 9:
469; EG-NEXT:     OR_INT * T0.W, T0.X, literal.x,
470; EG-NEXT:    256(3.587324e-43), 0(0.000000e+00)
471; EG-NEXT:     FFBL_INT T0.W, PV.W,
472; EG-NEXT:     AND_INT * T1.W, KC0[2].Y, literal.x,
473; EG-NEXT:    3(4.203895e-45), 0(0.000000e+00)
474; EG-NEXT:     AND_INT T0.W, PV.W, literal.x,
475; EG-NEXT:     LSHL * T1.W, PS, literal.y,
476; EG-NEXT:    255(3.573311e-43), 3(4.203895e-45)
477; EG-NEXT:     LSHL T0.X, PV.W, PS,
478; EG-NEXT:     LSHL * T0.W, literal.x, PS,
479; EG-NEXT:    255(3.573311e-43), 0(0.000000e+00)
480; EG-NEXT:     MOV T0.Y, 0.0,
481; EG-NEXT:     MOV * T0.Z, 0.0,
482; EG-NEXT:     LSHR * T1.X, KC0[2].Y, literal.x,
483; EG-NEXT:    2(2.802597e-45), 0(0.000000e+00)
484;
485; GFX10-LABEL: v_cttz_i8:
486; GFX10:       ; %bb.0:
487; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
488; GFX10-NEXT:    v_mov_b32_e32 v0, 0
489; GFX10-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
490; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
491; GFX10-NEXT:    global_load_ubyte v1, v0, s[2:3]
492; GFX10-NEXT:    s_waitcnt vmcnt(0)
493; GFX10-NEXT:    v_or_b32_e32 v1, 0x100, v1
494; GFX10-NEXT:    v_ffbl_b32_e32 v1, v1
495; GFX10-NEXT:    global_store_byte v0, v1, s[0:1]
496; GFX10-NEXT:    s_endpgm
497;
498; GFX10-GISEL-LABEL: v_cttz_i8:
499; GFX10-GISEL:       ; %bb.0:
500; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
501; GFX10-GISEL-NEXT:    v_mov_b32_e32 v0, 0
502; GFX10-GISEL-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
503; GFX10-GISEL-NEXT:    v_mov_b32_e32 v2, 0x100
504; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
505; GFX10-GISEL-NEXT:    global_load_ubyte v1, v0, s[2:3]
506; GFX10-GISEL-NEXT:    s_waitcnt vmcnt(0)
507; GFX10-GISEL-NEXT:    v_and_or_b32 v1, 0xff, v1, v2
508; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v1, v1
509; GFX10-GISEL-NEXT:    global_store_byte v0, v1, s[0:1]
510; GFX10-GISEL-NEXT:    s_endpgm
511  %val = load i8, i8 addrspace(1)* %valptr
512  %cttz = call i8 @llvm.cttz.i8(i8 %val, i1 false) nounwind readnone
513  store i8 %cttz, i8 addrspace(1)* %out
514  ret void
515}
516
517define amdgpu_kernel void @s_cttz_i64(i64 addrspace(1)* noalias %out, [8 x i32], i64 %val) nounwind {
518; SI-LABEL: s_cttz_i64:
519; SI:       ; %bb.0:
520; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x13
521; SI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
522; SI-NEXT:    s_mov_b32 s3, 0xf000
523; SI-NEXT:    s_mov_b32 s2, -1
524; SI-NEXT:    s_waitcnt lgkmcnt(0)
525; SI-NEXT:    s_ff1_i32_b32 s5, s5
526; SI-NEXT:    s_min_u32 s5, s5, 0xffffffdf
527; SI-NEXT:    s_add_i32 s5, s5, 32
528; SI-NEXT:    s_ff1_i32_b32 s4, s4
529; SI-NEXT:    v_mov_b32_e32 v0, s5
530; SI-NEXT:    v_min3_u32 v0, s4, v0, 64
531; SI-NEXT:    v_mov_b32_e32 v1, 0
532; SI-NEXT:    buffer_store_dwordx2 v[0:1], off, s[0:3], 0
533; SI-NEXT:    s_endpgm
534;
535; VI-LABEL: s_cttz_i64:
536; VI:       ; %bb.0:
537; VI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
538; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x4c
539; VI-NEXT:    s_mov_b32 s7, 0xf000
540; VI-NEXT:    s_mov_b32 s6, -1
541; VI-NEXT:    v_mov_b32_e32 v1, 0
542; VI-NEXT:    s_waitcnt lgkmcnt(0)
543; VI-NEXT:    s_ff1_i32_b32 s1, s1
544; VI-NEXT:    v_add_u32_e64 v0, s[2:3], s1, 32 clamp
545; VI-NEXT:    s_ff1_i32_b32 s0, s0
546; VI-NEXT:    v_min3_u32 v0, s0, v0, 64
547; VI-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
548; VI-NEXT:    s_endpgm
549;
550; EG-LABEL: s_cttz_i64:
551; EG:       ; %bb.0:
552; EG-NEXT:    ALU 9, @4, KC0[CB0:0-32], KC1[]
553; EG-NEXT:    MEM_RAT_CACHELESS STORE_RAW T0.XY, T1.X, 1
554; EG-NEXT:    CF_END
555; EG-NEXT:    PAD
556; EG-NEXT:    ALU clause starting at 4:
557; EG-NEXT:     FFBL_INT * T0.W, KC0[5].X,
558; EG-NEXT:     CNDE_INT * T0.W, KC0[5].X, literal.x, PV.W,
559; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
560; EG-NEXT:     FFBL_INT T1.W, KC0[4].W,
561; EG-NEXT:     ADD_INT * T0.W, PV.W, literal.x,
562; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
563; EG-NEXT:     CNDE_INT T0.X, KC0[4].W, PS, PV.W,
564; EG-NEXT:     MOV T0.Y, 0.0,
565; EG-NEXT:     LSHR * T1.X, KC0[2].Y, literal.x,
566; EG-NEXT:    2(2.802597e-45), 0(0.000000e+00)
567;
568; GFX10-LABEL: s_cttz_i64:
569; GFX10:       ; %bb.0:
570; GFX10-NEXT:    s_clause 0x1
571; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x4c
572; GFX10-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
573; GFX10-NEXT:    v_mov_b32_e32 v1, 0
574; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
575; GFX10-NEXT:    s_ff1_i32_b32 s0, s3
576; GFX10-NEXT:    v_add_nc_u32_e64 v0, s0, 32 clamp
577; GFX10-NEXT:    s_ff1_i32_b32 s0, s2
578; GFX10-NEXT:    v_min3_u32 v0, s0, v0, 64
579; GFX10-NEXT:    global_store_dwordx2 v1, v[0:1], s[4:5]
580; GFX10-NEXT:    s_endpgm
581;
582; GFX10-GISEL-LABEL: s_cttz_i64:
583; GFX10-GISEL:       ; %bb.0:
584; GFX10-GISEL-NEXT:    s_clause 0x1
585; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x4c
586; GFX10-GISEL-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
587; GFX10-GISEL-NEXT:    v_mov_b32_e32 v2, 0
588; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
589; GFX10-GISEL-NEXT:    s_ff1_i32_b64 s0, s[2:3]
590; GFX10-GISEL-NEXT:    s_cmp_eq_u64 s[2:3], 0
591; GFX10-GISEL-NEXT:    s_cselect_b32 s0, 64, s0
592; GFX10-GISEL-NEXT:    s_bfe_u64 s[0:1], s[0:1], 0x200000
593; GFX10-GISEL-NEXT:    v_mov_b32_e32 v0, s0
594; GFX10-GISEL-NEXT:    v_mov_b32_e32 v1, s1
595; GFX10-GISEL-NEXT:    global_store_dwordx2 v2, v[0:1], s[4:5]
596; GFX10-GISEL-NEXT:    s_endpgm
597  %cttz = call i64 @llvm.cttz.i64(i64 %val, i1 false)
598  store i64 %cttz, i64 addrspace(1)* %out
599  ret void
600}
601
602define amdgpu_kernel void @s_cttz_i64_trunc(i32 addrspace(1)* noalias %out, i64 %val) nounwind {
603; SI-LABEL: s_cttz_i64_trunc:
604; SI:       ; %bb.0:
605; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
606; SI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
607; SI-NEXT:    s_mov_b32 s3, 0xf000
608; SI-NEXT:    s_mov_b32 s2, -1
609; SI-NEXT:    s_waitcnt lgkmcnt(0)
610; SI-NEXT:    s_ff1_i32_b32 s5, s5
611; SI-NEXT:    s_min_u32 s5, s5, 0xffffffdf
612; SI-NEXT:    s_add_i32 s5, s5, 32
613; SI-NEXT:    s_ff1_i32_b32 s4, s4
614; SI-NEXT:    v_mov_b32_e32 v0, s5
615; SI-NEXT:    v_min3_u32 v0, s4, v0, 64
616; SI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
617; SI-NEXT:    s_endpgm
618;
619; VI-LABEL: s_cttz_i64_trunc:
620; VI:       ; %bb.0:
621; VI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
622; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x2c
623; VI-NEXT:    s_mov_b32 s7, 0xf000
624; VI-NEXT:    s_mov_b32 s6, -1
625; VI-NEXT:    s_waitcnt lgkmcnt(0)
626; VI-NEXT:    s_ff1_i32_b32 s1, s1
627; VI-NEXT:    v_add_u32_e64 v0, s[2:3], s1, 32 clamp
628; VI-NEXT:    s_ff1_i32_b32 s0, s0
629; VI-NEXT:    v_min3_u32 v0, s0, v0, 64
630; VI-NEXT:    buffer_store_dword v0, off, s[4:7], 0
631; VI-NEXT:    s_endpgm
632;
633; EG-LABEL: s_cttz_i64_trunc:
634; EG:       ; %bb.0:
635; EG-NEXT:    ALU 8, @4, KC0[CB0:0-32], KC1[]
636; EG-NEXT:    MEM_RAT_CACHELESS STORE_RAW T0.X, T1.X, 1
637; EG-NEXT:    CF_END
638; EG-NEXT:    PAD
639; EG-NEXT:    ALU clause starting at 4:
640; EG-NEXT:     FFBL_INT * T0.W, KC0[3].X,
641; EG-NEXT:     CNDE_INT * T0.W, KC0[3].X, literal.x, PV.W,
642; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
643; EG-NEXT:     FFBL_INT T1.W, KC0[2].W,
644; EG-NEXT:     ADD_INT * T0.W, PV.W, literal.x,
645; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
646; EG-NEXT:     CNDE_INT T0.X, KC0[2].W, PS, PV.W,
647; EG-NEXT:     LSHR * T1.X, KC0[2].Y, literal.x,
648; EG-NEXT:    2(2.802597e-45), 0(0.000000e+00)
649;
650; GFX10-LABEL: s_cttz_i64_trunc:
651; GFX10:       ; %bb.0:
652; GFX10-NEXT:    s_clause 0x1
653; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
654; GFX10-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
655; GFX10-NEXT:    v_mov_b32_e32 v1, 0
656; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
657; GFX10-NEXT:    s_ff1_i32_b32 s0, s3
658; GFX10-NEXT:    v_add_nc_u32_e64 v0, s0, 32 clamp
659; GFX10-NEXT:    s_ff1_i32_b32 s0, s2
660; GFX10-NEXT:    v_min3_u32 v0, s0, v0, 64
661; GFX10-NEXT:    global_store_dword v1, v0, s[4:5]
662; GFX10-NEXT:    s_endpgm
663;
664; GFX10-GISEL-LABEL: s_cttz_i64_trunc:
665; GFX10-GISEL:       ; %bb.0:
666; GFX10-GISEL-NEXT:    s_clause 0x1
667; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
668; GFX10-GISEL-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
669; GFX10-GISEL-NEXT:    v_mov_b32_e32 v1, 0
670; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
671; GFX10-GISEL-NEXT:    s_ff1_i32_b64 s0, s[2:3]
672; GFX10-GISEL-NEXT:    s_cmp_eq_u64 s[2:3], 0
673; GFX10-GISEL-NEXT:    s_cselect_b32 s0, 64, s0
674; GFX10-GISEL-NEXT:    v_mov_b32_e32 v0, s0
675; GFX10-GISEL-NEXT:    global_store_dword v1, v0, s[4:5]
676; GFX10-GISEL-NEXT:    s_endpgm
677  %cttz = call i64 @llvm.cttz.i64(i64 %val, i1 false)
678  %trunc = trunc i64 %cttz to i32
679  store i32 %trunc, i32 addrspace(1)* %out
680  ret void
681}
682
683define amdgpu_kernel void @v_cttz_i64(i64 addrspace(1)* noalias %out, i64 addrspace(1)* noalias %in) nounwind {
684; SI-LABEL: v_cttz_i64:
685; SI:       ; %bb.0:
686; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
687; SI-NEXT:    s_mov_b32 s7, 0xf000
688; SI-NEXT:    s_mov_b32 s6, 0
689; SI-NEXT:    v_lshlrev_b32_e32 v0, 3, v0
690; SI-NEXT:    v_mov_b32_e32 v1, 0
691; SI-NEXT:    s_waitcnt lgkmcnt(0)
692; SI-NEXT:    buffer_load_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64
693; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
694; SI-NEXT:    s_waitcnt vmcnt(0)
695; SI-NEXT:    v_ffbl_b32_e32 v3, v3
696; SI-NEXT:    v_min_u32_e32 v3, 0xffffffdf, v3
697; SI-NEXT:    v_add_i32_e32 v3, vcc, 32, v3
698; SI-NEXT:    v_ffbl_b32_e32 v2, v2
699; SI-NEXT:    v_min3_u32 v2, v2, v3, 64
700; SI-NEXT:    v_mov_b32_e32 v3, v1
701; SI-NEXT:    s_waitcnt lgkmcnt(0)
702; SI-NEXT:    buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64
703; SI-NEXT:    s_endpgm
704;
705; VI-LABEL: v_cttz_i64:
706; VI:       ; %bb.0:
707; VI-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x24
708; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x2c
709; VI-NEXT:    v_lshlrev_b32_e32 v3, 3, v0
710; VI-NEXT:    v_mov_b32_e32 v2, 0
711; VI-NEXT:    s_waitcnt lgkmcnt(0)
712; VI-NEXT:    v_mov_b32_e32 v4, s3
713; VI-NEXT:    v_mov_b32_e32 v1, s1
714; VI-NEXT:    v_add_u32_e32 v0, vcc, s0, v3
715; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
716; VI-NEXT:    flat_load_dwordx2 v[0:1], v[0:1]
717; VI-NEXT:    v_add_u32_e32 v3, vcc, s2, v3
718; VI-NEXT:    v_addc_u32_e32 v4, vcc, 0, v4, vcc
719; VI-NEXT:    s_waitcnt vmcnt(0)
720; VI-NEXT:    v_ffbl_b32_e32 v1, v1
721; VI-NEXT:    v_add_u32_e64 v1, s[0:1], v1, 32 clamp
722; VI-NEXT:    v_ffbl_b32_e32 v0, v0
723; VI-NEXT:    v_min3_u32 v1, v0, v1, 64
724; VI-NEXT:    flat_store_dwordx2 v[3:4], v[1:2]
725; VI-NEXT:    s_endpgm
726;
727; EG-LABEL: v_cttz_i64:
728; EG:       ; %bb.0:
729; EG-NEXT:    ALU 2, @8, KC0[CB0:0-32], KC1[]
730; EG-NEXT:    TEX 0 @6
731; EG-NEXT:    ALU 10, @11, KC0[CB0:0-32], KC1[]
732; EG-NEXT:    MEM_RAT_CACHELESS STORE_RAW T0.XY, T1.X, 1
733; EG-NEXT:    CF_END
734; EG-NEXT:    PAD
735; EG-NEXT:    Fetch clause starting at 6:
736; EG-NEXT:     VTX_READ_64 T0.XY, T0.X, 0, #1
737; EG-NEXT:    ALU clause starting at 8:
738; EG-NEXT:     LSHL * T0.W, T0.X, literal.x,
739; EG-NEXT:    3(4.203895e-45), 0(0.000000e+00)
740; EG-NEXT:     ADD_INT * T0.X, KC0[2].Z, PV.W,
741; EG-NEXT:    ALU clause starting at 11:
742; EG-NEXT:     FFBL_INT * T1.W, T0.Y,
743; EG-NEXT:     CNDE_INT * T1.W, T0.Y, literal.x, PV.W,
744; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
745; EG-NEXT:     FFBL_INT T2.W, T0.X,
746; EG-NEXT:     ADD_INT * T1.W, PV.W, literal.x,
747; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
748; EG-NEXT:     CNDE_INT T0.X, T0.X, PS, PV.W,
749; EG-NEXT:     MOV T0.Y, 0.0,
750; EG-NEXT:     ADD_INT * T0.W, KC0[2].Y, T0.W,
751; EG-NEXT:     LSHR * T1.X, PV.W, literal.x,
752; EG-NEXT:    2(2.802597e-45), 0(0.000000e+00)
753;
754; GFX10-LABEL: v_cttz_i64:
755; GFX10:       ; %bb.0:
756; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
757; GFX10-NEXT:    v_lshlrev_b32_e32 v2, 3, v0
758; GFX10-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
759; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
760; GFX10-NEXT:    global_load_dwordx2 v[0:1], v2, s[2:3]
761; GFX10-NEXT:    s_waitcnt vmcnt(0)
762; GFX10-NEXT:    v_ffbl_b32_e32 v1, v1
763; GFX10-NEXT:    v_ffbl_b32_e32 v0, v0
764; GFX10-NEXT:    v_add_nc_u32_e64 v1, v1, 32 clamp
765; GFX10-NEXT:    v_min3_u32 v0, v0, v1, 64
766; GFX10-NEXT:    v_mov_b32_e32 v1, 0
767; GFX10-NEXT:    global_store_dwordx2 v2, v[0:1], s[0:1]
768; GFX10-NEXT:    s_endpgm
769;
770; GFX10-GISEL-LABEL: v_cttz_i64:
771; GFX10-GISEL:       ; %bb.0:
772; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
773; GFX10-GISEL-NEXT:    v_lshlrev_b32_e32 v2, 3, v0
774; GFX10-GISEL-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
775; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
776; GFX10-GISEL-NEXT:    global_load_dwordx2 v[0:1], v2, s[2:3]
777; GFX10-GISEL-NEXT:    s_waitcnt vmcnt(0)
778; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v3, v1
779; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v4, v0
780; GFX10-GISEL-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[0:1]
781; GFX10-GISEL-NEXT:    v_mov_b32_e32 v1, 0
782; GFX10-GISEL-NEXT:    v_add_nc_u32_e32 v3, 32, v3
783; GFX10-GISEL-NEXT:    v_min_u32_e32 v3, v4, v3
784; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v0, v3, 64, vcc_lo
785; GFX10-GISEL-NEXT:    global_store_dwordx2 v2, v[0:1], s[0:1]
786; GFX10-GISEL-NEXT:    s_endpgm
787  %tid = call i32 @llvm.amdgcn.workitem.id.x()
788  %in.gep = getelementptr i64, i64 addrspace(1)* %in, i32 %tid
789  %out.gep = getelementptr i64, i64 addrspace(1)* %out, i32 %tid
790  %val = load i64, i64 addrspace(1)* %in.gep
791  %cttz = call i64 @llvm.cttz.i64(i64 %val, i1 false)
792  store i64 %cttz, i64 addrspace(1)* %out.gep
793  ret void
794}
795
796define amdgpu_kernel void @v_cttz_i64_trunc(i32 addrspace(1)* noalias %out, i64 addrspace(1)* noalias %in) nounwind {
797; SI-LABEL: v_cttz_i64_trunc:
798; SI:       ; %bb.0:
799; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
800; SI-NEXT:    s_mov_b32 s7, 0xf000
801; SI-NEXT:    s_mov_b32 s6, 0
802; SI-NEXT:    v_lshlrev_b32_e32 v1, 3, v0
803; SI-NEXT:    v_mov_b32_e32 v2, 0
804; SI-NEXT:    s_waitcnt lgkmcnt(0)
805; SI-NEXT:    buffer_load_dwordx2 v[3:4], v[1:2], s[4:7], 0 addr64
806; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x9
807; SI-NEXT:    v_lshlrev_b32_e32 v1, 2, v0
808; SI-NEXT:    s_waitcnt vmcnt(0)
809; SI-NEXT:    v_ffbl_b32_e32 v0, v4
810; SI-NEXT:    v_min_u32_e32 v0, 0xffffffdf, v0
811; SI-NEXT:    v_add_i32_e32 v0, vcc, 32, v0
812; SI-NEXT:    v_ffbl_b32_e32 v3, v3
813; SI-NEXT:    v_min3_u32 v0, v3, v0, 64
814; SI-NEXT:    s_waitcnt lgkmcnt(0)
815; SI-NEXT:    buffer_store_dword v0, v[1:2], s[4:7], 0 addr64
816; SI-NEXT:    s_endpgm
817;
818; VI-LABEL: v_cttz_i64_trunc:
819; VI:       ; %bb.0:
820; VI-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x24
821; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x2c
822; VI-NEXT:    v_lshlrev_b32_e32 v1, 3, v0
823; VI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
824; VI-NEXT:    s_waitcnt lgkmcnt(0)
825; VI-NEXT:    v_mov_b32_e32 v4, s3
826; VI-NEXT:    v_mov_b32_e32 v2, s1
827; VI-NEXT:    v_add_u32_e32 v1, vcc, s0, v1
828; VI-NEXT:    v_addc_u32_e32 v2, vcc, 0, v2, vcc
829; VI-NEXT:    flat_load_dwordx2 v[1:2], v[1:2]
830; VI-NEXT:    v_add_u32_e32 v3, vcc, s2, v0
831; VI-NEXT:    v_addc_u32_e32 v4, vcc, 0, v4, vcc
832; VI-NEXT:    s_waitcnt vmcnt(0)
833; VI-NEXT:    v_ffbl_b32_e32 v0, v2
834; VI-NEXT:    v_add_u32_e64 v0, s[0:1], v0, 32 clamp
835; VI-NEXT:    v_ffbl_b32_e32 v1, v1
836; VI-NEXT:    v_min3_u32 v0, v1, v0, 64
837; VI-NEXT:    flat_store_dword v[3:4], v0
838; VI-NEXT:    s_endpgm
839;
840; EG-LABEL: v_cttz_i64_trunc:
841; EG:       ; %bb.0:
842; EG-NEXT:    ALU 2, @8, KC0[CB0:0-32], KC1[]
843; EG-NEXT:    TEX 0 @6
844; EG-NEXT:    ALU 10, @11, KC0[CB0:0-32], KC1[]
845; EG-NEXT:    MEM_RAT_CACHELESS STORE_RAW T0.X, T1.X, 1
846; EG-NEXT:    CF_END
847; EG-NEXT:    PAD
848; EG-NEXT:    Fetch clause starting at 6:
849; EG-NEXT:     VTX_READ_64 T1.XY, T1.X, 0, #1
850; EG-NEXT:    ALU clause starting at 8:
851; EG-NEXT:     LSHL * T0.W, T0.X, literal.x,
852; EG-NEXT:    3(4.203895e-45), 0(0.000000e+00)
853; EG-NEXT:     ADD_INT * T1.X, KC0[2].Z, PV.W,
854; EG-NEXT:    ALU clause starting at 11:
855; EG-NEXT:     FFBL_INT * T0.W, T1.Y,
856; EG-NEXT:     CNDE_INT * T0.W, T1.Y, literal.x, PV.W,
857; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
858; EG-NEXT:     LSHL T0.Z, T0.X, literal.x,
859; EG-NEXT:     FFBL_INT T1.W, T1.X, BS:VEC_120/SCL_212
860; EG-NEXT:     ADD_INT * T0.W, PV.W, literal.y,
861; EG-NEXT:    2(2.802597e-45), 32(4.484155e-44)
862; EG-NEXT:     CNDE_INT T0.X, T1.X, PS, PV.W,
863; EG-NEXT:     ADD_INT * T0.W, KC0[2].Y, PV.Z,
864; EG-NEXT:     LSHR * T1.X, PV.W, literal.x,
865; EG-NEXT:    2(2.802597e-45), 0(0.000000e+00)
866;
867; GFX10-LABEL: v_cttz_i64_trunc:
868; GFX10:       ; %bb.0:
869; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
870; GFX10-NEXT:    v_lshlrev_b32_e32 v1, 3, v0
871; GFX10-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
872; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
873; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
874; GFX10-NEXT:    global_load_dwordx2 v[1:2], v1, s[2:3]
875; GFX10-NEXT:    s_waitcnt vmcnt(0)
876; GFX10-NEXT:    v_ffbl_b32_e32 v2, v2
877; GFX10-NEXT:    v_ffbl_b32_e32 v1, v1
878; GFX10-NEXT:    v_add_nc_u32_e64 v2, v2, 32 clamp
879; GFX10-NEXT:    v_min3_u32 v1, v1, v2, 64
880; GFX10-NEXT:    global_store_dword v0, v1, s[0:1]
881; GFX10-NEXT:    s_endpgm
882;
883; GFX10-GISEL-LABEL: v_cttz_i64_trunc:
884; GFX10-GISEL:       ; %bb.0:
885; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
886; GFX10-GISEL-NEXT:    v_lshlrev_b32_e32 v1, 3, v0
887; GFX10-GISEL-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
888; GFX10-GISEL-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
889; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
890; GFX10-GISEL-NEXT:    global_load_dwordx2 v[1:2], v1, s[2:3]
891; GFX10-GISEL-NEXT:    s_waitcnt vmcnt(0)
892; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v3, v2
893; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v4, v1
894; GFX10-GISEL-NEXT:    v_cmp_eq_u64_e32 vcc_lo, 0, v[1:2]
895; GFX10-GISEL-NEXT:    v_add_nc_u32_e32 v3, 32, v3
896; GFX10-GISEL-NEXT:    v_min_u32_e32 v3, v4, v3
897; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v1, v3, 64, vcc_lo
898; GFX10-GISEL-NEXT:    global_store_dword v0, v1, s[0:1]
899; GFX10-GISEL-NEXT:    s_endpgm
900  %tid = call i32 @llvm.amdgcn.workitem.id.x()
901  %in.gep = getelementptr i64, i64 addrspace(1)* %in, i32 %tid
902  %out.gep = getelementptr i32, i32 addrspace(1)* %out, i32 %tid
903  %val = load i64, i64 addrspace(1)* %in.gep
904  %cttz = call i64 @llvm.cttz.i64(i64 %val, i1 false)
905  %trunc = trunc i64 %cttz to i32
906  store i32 %trunc, i32 addrspace(1)* %out.gep
907  ret void
908}
909
910define amdgpu_kernel void @v_cttz_i32_sel_eq_neg1(i32 addrspace(1)* noalias %out, i32 addrspace(1)* noalias %valptr) nounwind {
911; SI-LABEL: v_cttz_i32_sel_eq_neg1:
912; SI:       ; %bb.0:
913; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
914; SI-NEXT:    s_mov_b32 s3, 0xf000
915; SI-NEXT:    s_mov_b32 s6, 0
916; SI-NEXT:    s_mov_b32 s7, s3
917; SI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
918; SI-NEXT:    v_mov_b32_e32 v1, 0
919; SI-NEXT:    s_waitcnt lgkmcnt(0)
920; SI-NEXT:    buffer_load_dword v0, v[0:1], s[4:7], 0 addr64
921; SI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
922; SI-NEXT:    s_mov_b32 s2, -1
923; SI-NEXT:    s_waitcnt vmcnt(0)
924; SI-NEXT:    v_ffbl_b32_e32 v0, v0
925; SI-NEXT:    s_waitcnt lgkmcnt(0)
926; SI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
927; SI-NEXT:    s_endpgm
928;
929; VI-LABEL: v_cttz_i32_sel_eq_neg1:
930; VI:       ; %bb.0:
931; VI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
932; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x2c
933; VI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
934; VI-NEXT:    s_mov_b32 s7, 0xf000
935; VI-NEXT:    s_mov_b32 s6, -1
936; VI-NEXT:    s_waitcnt lgkmcnt(0)
937; VI-NEXT:    v_mov_b32_e32 v1, s1
938; VI-NEXT:    v_add_u32_e32 v0, vcc, s0, v0
939; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
940; VI-NEXT:    flat_load_dword v0, v[0:1]
941; VI-NEXT:    s_waitcnt vmcnt(0)
942; VI-NEXT:    v_ffbl_b32_e32 v0, v0
943; VI-NEXT:    buffer_store_dword v0, off, s[4:7], 0
944; VI-NEXT:    s_endpgm
945;
946; EG-LABEL: v_cttz_i32_sel_eq_neg1:
947; EG:       ; %bb.0:
948; EG-NEXT:    ALU 2, @8, KC0[CB0:0-32], KC1[]
949; EG-NEXT:    TEX 0 @6
950; EG-NEXT:    ALU 5, @11, KC0[CB0:0-32], KC1[]
951; EG-NEXT:    MEM_RAT_CACHELESS STORE_RAW T0.X, T1.X, 1
952; EG-NEXT:    CF_END
953; EG-NEXT:    PAD
954; EG-NEXT:    Fetch clause starting at 6:
955; EG-NEXT:     VTX_READ_32 T0.X, T0.X, 0, #1
956; EG-NEXT:    ALU clause starting at 8:
957; EG-NEXT:     LSHL * T0.W, T0.X, literal.x,
958; EG-NEXT:    2(2.802597e-45), 0(0.000000e+00)
959; EG-NEXT:     ADD_INT * T0.X, KC0[2].Z, PV.W,
960; EG-NEXT:    ALU clause starting at 11:
961; EG-NEXT:     FFBL_INT * T0.W, T0.X,
962; EG-NEXT:     CNDE_INT * T0.W, T0.X, literal.x, PV.W,
963; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
964; EG-NEXT:     CNDE_INT T0.X, T0.X, literal.x, PV.W,
965; EG-NEXT:     LSHR * T1.X, KC0[2].Y, literal.y,
966; EG-NEXT:    -1(nan), 2(2.802597e-45)
967;
968; GFX10-LABEL: v_cttz_i32_sel_eq_neg1:
969; GFX10:       ; %bb.0:
970; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
971; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
972; GFX10-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
973; GFX10-NEXT:    v_mov_b32_e32 v1, 0
974; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
975; GFX10-NEXT:    global_load_dword v0, v0, s[2:3]
976; GFX10-NEXT:    s_waitcnt vmcnt(0)
977; GFX10-NEXT:    v_ffbl_b32_e32 v0, v0
978; GFX10-NEXT:    global_store_dword v1, v0, s[0:1]
979; GFX10-NEXT:    s_endpgm
980;
981; GFX10-GISEL-LABEL: v_cttz_i32_sel_eq_neg1:
982; GFX10-GISEL:       ; %bb.0:
983; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
984; GFX10-GISEL-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
985; GFX10-GISEL-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
986; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
987; GFX10-GISEL-NEXT:    global_load_dword v0, v0, s[2:3]
988; GFX10-GISEL-NEXT:    s_waitcnt vmcnt(0)
989; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v1, v0
990; GFX10-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
991; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v0, v1, 32, vcc_lo
992; GFX10-GISEL-NEXT:    v_mov_b32_e32 v1, 0
993; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v0, v0, -1, vcc_lo
994; GFX10-GISEL-NEXT:    global_store_dword v1, v0, s[0:1]
995; GFX10-GISEL-NEXT:    s_endpgm
996  %tid = call i32 @llvm.amdgcn.workitem.id.x()
997  %in.gep = getelementptr i32, i32 addrspace(1)* %valptr, i32 %tid
998  %val = load i32, i32 addrspace(1)* %in.gep
999  %cttz = call i32 @llvm.cttz.i32(i32 %val, i1 false) nounwind readnone
1000  %cmp = icmp eq i32 %val, 0
1001  %sel = select i1 %cmp, i32 -1, i32 %cttz
1002  store i32 %sel, i32 addrspace(1)* %out
1003  ret void
1004}
1005
1006define amdgpu_kernel void @v_cttz_i32_sel_ne_neg1(i32 addrspace(1)* noalias %out, i32 addrspace(1)* noalias %valptr) nounwind {
1007; SI-LABEL: v_cttz_i32_sel_ne_neg1:
1008; SI:       ; %bb.0:
1009; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
1010; SI-NEXT:    s_mov_b32 s3, 0xf000
1011; SI-NEXT:    s_mov_b32 s6, 0
1012; SI-NEXT:    s_mov_b32 s7, s3
1013; SI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
1014; SI-NEXT:    v_mov_b32_e32 v1, 0
1015; SI-NEXT:    s_waitcnt lgkmcnt(0)
1016; SI-NEXT:    buffer_load_dword v0, v[0:1], s[4:7], 0 addr64
1017; SI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
1018; SI-NEXT:    s_mov_b32 s2, -1
1019; SI-NEXT:    s_waitcnt vmcnt(0)
1020; SI-NEXT:    v_ffbl_b32_e32 v0, v0
1021; SI-NEXT:    s_waitcnt lgkmcnt(0)
1022; SI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
1023; SI-NEXT:    s_endpgm
1024;
1025; VI-LABEL: v_cttz_i32_sel_ne_neg1:
1026; VI:       ; %bb.0:
1027; VI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
1028; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x2c
1029; VI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
1030; VI-NEXT:    s_mov_b32 s7, 0xf000
1031; VI-NEXT:    s_mov_b32 s6, -1
1032; VI-NEXT:    s_waitcnt lgkmcnt(0)
1033; VI-NEXT:    v_mov_b32_e32 v1, s1
1034; VI-NEXT:    v_add_u32_e32 v0, vcc, s0, v0
1035; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
1036; VI-NEXT:    flat_load_dword v0, v[0:1]
1037; VI-NEXT:    s_waitcnt vmcnt(0)
1038; VI-NEXT:    v_ffbl_b32_e32 v0, v0
1039; VI-NEXT:    buffer_store_dword v0, off, s[4:7], 0
1040; VI-NEXT:    s_endpgm
1041;
1042; EG-LABEL: v_cttz_i32_sel_ne_neg1:
1043; EG:       ; %bb.0:
1044; EG-NEXT:    ALU 2, @8, KC0[CB0:0-32], KC1[]
1045; EG-NEXT:    TEX 0 @6
1046; EG-NEXT:    ALU 5, @11, KC0[CB0:0-32], KC1[]
1047; EG-NEXT:    MEM_RAT_CACHELESS STORE_RAW T0.X, T1.X, 1
1048; EG-NEXT:    CF_END
1049; EG-NEXT:    PAD
1050; EG-NEXT:    Fetch clause starting at 6:
1051; EG-NEXT:     VTX_READ_32 T0.X, T0.X, 0, #1
1052; EG-NEXT:    ALU clause starting at 8:
1053; EG-NEXT:     LSHL * T0.W, T0.X, literal.x,
1054; EG-NEXT:    2(2.802597e-45), 0(0.000000e+00)
1055; EG-NEXT:     ADD_INT * T0.X, KC0[2].Z, PV.W,
1056; EG-NEXT:    ALU clause starting at 11:
1057; EG-NEXT:     FFBL_INT * T0.W, T0.X,
1058; EG-NEXT:     CNDE_INT * T0.W, T0.X, literal.x, PV.W,
1059; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
1060; EG-NEXT:     CNDE_INT T0.X, T0.X, literal.x, PV.W,
1061; EG-NEXT:     LSHR * T1.X, KC0[2].Y, literal.y,
1062; EG-NEXT:    -1(nan), 2(2.802597e-45)
1063;
1064; GFX10-LABEL: v_cttz_i32_sel_ne_neg1:
1065; GFX10:       ; %bb.0:
1066; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
1067; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
1068; GFX10-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
1069; GFX10-NEXT:    v_mov_b32_e32 v1, 0
1070; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
1071; GFX10-NEXT:    global_load_dword v0, v0, s[2:3]
1072; GFX10-NEXT:    s_waitcnt vmcnt(0)
1073; GFX10-NEXT:    v_ffbl_b32_e32 v0, v0
1074; GFX10-NEXT:    global_store_dword v1, v0, s[0:1]
1075; GFX10-NEXT:    s_endpgm
1076;
1077; GFX10-GISEL-LABEL: v_cttz_i32_sel_ne_neg1:
1078; GFX10-GISEL:       ; %bb.0:
1079; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
1080; GFX10-GISEL-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
1081; GFX10-GISEL-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
1082; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
1083; GFX10-GISEL-NEXT:    global_load_dword v0, v0, s[2:3]
1084; GFX10-GISEL-NEXT:    s_waitcnt vmcnt(0)
1085; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v1, v0
1086; GFX10-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
1087; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v1, v1, 32, vcc_lo
1088; GFX10-GISEL-NEXT:    v_cmp_ne_u32_e32 vcc_lo, 0, v0
1089; GFX10-GISEL-NEXT:    v_cndmask_b32_e32 v0, -1, v1, vcc_lo
1090; GFX10-GISEL-NEXT:    v_mov_b32_e32 v1, 0
1091; GFX10-GISEL-NEXT:    global_store_dword v1, v0, s[0:1]
1092; GFX10-GISEL-NEXT:    s_endpgm
1093  %tid = call i32 @llvm.amdgcn.workitem.id.x()
1094  %in.gep = getelementptr i32, i32 addrspace(1)* %valptr, i32 %tid
1095  %val = load i32, i32 addrspace(1)* %in.gep
1096  %cttz = call i32 @llvm.cttz.i32(i32 %val, i1 false) nounwind readnone
1097  %cmp = icmp ne i32 %val, 0
1098  %sel = select i1 %cmp, i32 %cttz, i32 -1
1099  store i32 %sel, i32 addrspace(1)* %out
1100  ret void
1101}
1102
1103; TODO: Should be able to eliminate select here as well.
1104define amdgpu_kernel void @v_cttz_i32_sel_eq_bitwidth(i32 addrspace(1)* noalias %out, i32 addrspace(1)* noalias %valptr) nounwind {
1105; SI-LABEL: v_cttz_i32_sel_eq_bitwidth:
1106; SI:       ; %bb.0:
1107; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
1108; SI-NEXT:    s_mov_b32 s3, 0xf000
1109; SI-NEXT:    s_mov_b32 s6, 0
1110; SI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
1111; SI-NEXT:    v_mov_b32_e32 v1, 0
1112; SI-NEXT:    s_mov_b32 s7, s3
1113; SI-NEXT:    s_waitcnt lgkmcnt(0)
1114; SI-NEXT:    buffer_load_dword v0, v[0:1], s[4:7], 0 addr64
1115; SI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
1116; SI-NEXT:    s_mov_b32 s2, -1
1117; SI-NEXT:    s_waitcnt vmcnt(0)
1118; SI-NEXT:    v_ffbl_b32_e32 v0, v0
1119; SI-NEXT:    v_min_u32_e32 v0, 32, v0
1120; SI-NEXT:    v_cmp_ne_u32_e32 vcc, 32, v0
1121; SI-NEXT:    v_cndmask_b32_e32 v0, -1, v0, vcc
1122; SI-NEXT:    s_waitcnt lgkmcnt(0)
1123; SI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
1124; SI-NEXT:    s_endpgm
1125;
1126; VI-LABEL: v_cttz_i32_sel_eq_bitwidth:
1127; VI:       ; %bb.0:
1128; VI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
1129; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x2c
1130; VI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
1131; VI-NEXT:    s_mov_b32 s7, 0xf000
1132; VI-NEXT:    s_mov_b32 s6, -1
1133; VI-NEXT:    s_waitcnt lgkmcnt(0)
1134; VI-NEXT:    v_mov_b32_e32 v1, s1
1135; VI-NEXT:    v_add_u32_e32 v0, vcc, s0, v0
1136; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
1137; VI-NEXT:    flat_load_dword v0, v[0:1]
1138; VI-NEXT:    s_waitcnt vmcnt(0)
1139; VI-NEXT:    v_ffbl_b32_e32 v0, v0
1140; VI-NEXT:    v_min_u32_e32 v0, 32, v0
1141; VI-NEXT:    v_cmp_ne_u32_e32 vcc, 32, v0
1142; VI-NEXT:    v_cndmask_b32_e32 v0, -1, v0, vcc
1143; VI-NEXT:    buffer_store_dword v0, off, s[4:7], 0
1144; VI-NEXT:    s_endpgm
1145;
1146; EG-LABEL: v_cttz_i32_sel_eq_bitwidth:
1147; EG:       ; %bb.0:
1148; EG-NEXT:    ALU 2, @8, KC0[CB0:0-32], KC1[]
1149; EG-NEXT:    TEX 0 @6
1150; EG-NEXT:    ALU 7, @11, KC0[CB0:0-32], KC1[]
1151; EG-NEXT:    MEM_RAT_CACHELESS STORE_RAW T0.X, T1.X, 1
1152; EG-NEXT:    CF_END
1153; EG-NEXT:    PAD
1154; EG-NEXT:    Fetch clause starting at 6:
1155; EG-NEXT:     VTX_READ_32 T0.X, T0.X, 0, #1
1156; EG-NEXT:    ALU clause starting at 8:
1157; EG-NEXT:     LSHL * T0.W, T0.X, literal.x,
1158; EG-NEXT:    2(2.802597e-45), 0(0.000000e+00)
1159; EG-NEXT:     ADD_INT * T0.X, KC0[2].Z, PV.W,
1160; EG-NEXT:    ALU clause starting at 11:
1161; EG-NEXT:     FFBL_INT * T0.W, T0.X,
1162; EG-NEXT:     CNDE_INT * T0.W, T0.X, literal.x, PV.W,
1163; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
1164; EG-NEXT:     SETE_INT * T1.W, PV.W, literal.x,
1165; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
1166; EG-NEXT:     CNDE_INT T0.X, PV.W, T0.W, literal.x,
1167; EG-NEXT:     LSHR * T1.X, KC0[2].Y, literal.y,
1168; EG-NEXT:    -1(nan), 2(2.802597e-45)
1169;
1170; GFX10-LABEL: v_cttz_i32_sel_eq_bitwidth:
1171; GFX10:       ; %bb.0:
1172; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
1173; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
1174; GFX10-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
1175; GFX10-NEXT:    v_mov_b32_e32 v1, 0
1176; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
1177; GFX10-NEXT:    global_load_dword v0, v0, s[2:3]
1178; GFX10-NEXT:    s_waitcnt vmcnt(0)
1179; GFX10-NEXT:    v_ffbl_b32_e32 v0, v0
1180; GFX10-NEXT:    v_min_u32_e32 v0, 32, v0
1181; GFX10-NEXT:    v_cmp_ne_u32_e32 vcc_lo, 32, v0
1182; GFX10-NEXT:    v_cndmask_b32_e32 v0, -1, v0, vcc_lo
1183; GFX10-NEXT:    global_store_dword v1, v0, s[0:1]
1184; GFX10-NEXT:    s_endpgm
1185;
1186; GFX10-GISEL-LABEL: v_cttz_i32_sel_eq_bitwidth:
1187; GFX10-GISEL:       ; %bb.0:
1188; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
1189; GFX10-GISEL-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
1190; GFX10-GISEL-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
1191; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
1192; GFX10-GISEL-NEXT:    global_load_dword v0, v0, s[2:3]
1193; GFX10-GISEL-NEXT:    s_waitcnt vmcnt(0)
1194; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v1, v0
1195; GFX10-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
1196; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v0, v1, 32, vcc_lo
1197; GFX10-GISEL-NEXT:    v_mov_b32_e32 v1, 0
1198; GFX10-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 32, v0
1199; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v0, v0, -1, vcc_lo
1200; GFX10-GISEL-NEXT:    global_store_dword v1, v0, s[0:1]
1201; GFX10-GISEL-NEXT:    s_endpgm
1202  %tid = call i32 @llvm.amdgcn.workitem.id.x()
1203  %in.gep = getelementptr i32, i32 addrspace(1)* %valptr, i32 %tid
1204  %val = load i32, i32 addrspace(1)* %in.gep
1205  %cttz = call i32 @llvm.cttz.i32(i32 %val, i1 false) nounwind readnone
1206  %cmp = icmp eq i32 %cttz, 32
1207  %sel = select i1 %cmp, i32 -1, i32 %cttz
1208  store i32 %sel, i32 addrspace(1)* %out
1209  ret void
1210}
1211
1212define amdgpu_kernel void @v_cttz_i32_sel_ne_bitwidth(i32 addrspace(1)* noalias %out, i32 addrspace(1)* noalias %valptr) nounwind {
1213; SI-LABEL: v_cttz_i32_sel_ne_bitwidth:
1214; SI:       ; %bb.0:
1215; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
1216; SI-NEXT:    s_mov_b32 s3, 0xf000
1217; SI-NEXT:    s_mov_b32 s6, 0
1218; SI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
1219; SI-NEXT:    v_mov_b32_e32 v1, 0
1220; SI-NEXT:    s_mov_b32 s7, s3
1221; SI-NEXT:    s_waitcnt lgkmcnt(0)
1222; SI-NEXT:    buffer_load_dword v0, v[0:1], s[4:7], 0 addr64
1223; SI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
1224; SI-NEXT:    s_mov_b32 s2, -1
1225; SI-NEXT:    s_waitcnt vmcnt(0)
1226; SI-NEXT:    v_ffbl_b32_e32 v0, v0
1227; SI-NEXT:    v_min_u32_e32 v0, 32, v0
1228; SI-NEXT:    v_cmp_ne_u32_e32 vcc, 32, v0
1229; SI-NEXT:    v_cndmask_b32_e32 v0, -1, v0, vcc
1230; SI-NEXT:    s_waitcnt lgkmcnt(0)
1231; SI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
1232; SI-NEXT:    s_endpgm
1233;
1234; VI-LABEL: v_cttz_i32_sel_ne_bitwidth:
1235; VI:       ; %bb.0:
1236; VI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
1237; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x2c
1238; VI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
1239; VI-NEXT:    s_mov_b32 s7, 0xf000
1240; VI-NEXT:    s_mov_b32 s6, -1
1241; VI-NEXT:    s_waitcnt lgkmcnt(0)
1242; VI-NEXT:    v_mov_b32_e32 v1, s1
1243; VI-NEXT:    v_add_u32_e32 v0, vcc, s0, v0
1244; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
1245; VI-NEXT:    flat_load_dword v0, v[0:1]
1246; VI-NEXT:    s_waitcnt vmcnt(0)
1247; VI-NEXT:    v_ffbl_b32_e32 v0, v0
1248; VI-NEXT:    v_min_u32_e32 v0, 32, v0
1249; VI-NEXT:    v_cmp_ne_u32_e32 vcc, 32, v0
1250; VI-NEXT:    v_cndmask_b32_e32 v0, -1, v0, vcc
1251; VI-NEXT:    buffer_store_dword v0, off, s[4:7], 0
1252; VI-NEXT:    s_endpgm
1253;
1254; EG-LABEL: v_cttz_i32_sel_ne_bitwidth:
1255; EG:       ; %bb.0:
1256; EG-NEXT:    ALU 2, @8, KC0[CB0:0-32], KC1[]
1257; EG-NEXT:    TEX 0 @6
1258; EG-NEXT:    ALU 7, @11, KC0[CB0:0-32], KC1[]
1259; EG-NEXT:    MEM_RAT_CACHELESS STORE_RAW T0.X, T1.X, 1
1260; EG-NEXT:    CF_END
1261; EG-NEXT:    PAD
1262; EG-NEXT:    Fetch clause starting at 6:
1263; EG-NEXT:     VTX_READ_32 T0.X, T0.X, 0, #1
1264; EG-NEXT:    ALU clause starting at 8:
1265; EG-NEXT:     LSHL * T0.W, T0.X, literal.x,
1266; EG-NEXT:    2(2.802597e-45), 0(0.000000e+00)
1267; EG-NEXT:     ADD_INT * T0.X, KC0[2].Z, PV.W,
1268; EG-NEXT:    ALU clause starting at 11:
1269; EG-NEXT:     FFBL_INT * T0.W, T0.X,
1270; EG-NEXT:     CNDE_INT * T0.W, T0.X, literal.x, PV.W,
1271; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
1272; EG-NEXT:     SETNE_INT * T1.W, PV.W, literal.x,
1273; EG-NEXT:    32(4.484155e-44), 0(0.000000e+00)
1274; EG-NEXT:     CNDE_INT T0.X, PV.W, literal.x, T0.W,
1275; EG-NEXT:     LSHR * T1.X, KC0[2].Y, literal.y,
1276; EG-NEXT:    -1(nan), 2(2.802597e-45)
1277;
1278; GFX10-LABEL: v_cttz_i32_sel_ne_bitwidth:
1279; GFX10:       ; %bb.0:
1280; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
1281; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
1282; GFX10-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
1283; GFX10-NEXT:    v_mov_b32_e32 v1, 0
1284; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
1285; GFX10-NEXT:    global_load_dword v0, v0, s[2:3]
1286; GFX10-NEXT:    s_waitcnt vmcnt(0)
1287; GFX10-NEXT:    v_ffbl_b32_e32 v0, v0
1288; GFX10-NEXT:    v_min_u32_e32 v0, 32, v0
1289; GFX10-NEXT:    v_cmp_ne_u32_e32 vcc_lo, 32, v0
1290; GFX10-NEXT:    v_cndmask_b32_e32 v0, -1, v0, vcc_lo
1291; GFX10-NEXT:    global_store_dword v1, v0, s[0:1]
1292; GFX10-NEXT:    s_endpgm
1293;
1294; GFX10-GISEL-LABEL: v_cttz_i32_sel_ne_bitwidth:
1295; GFX10-GISEL:       ; %bb.0:
1296; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
1297; GFX10-GISEL-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
1298; GFX10-GISEL-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
1299; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
1300; GFX10-GISEL-NEXT:    global_load_dword v0, v0, s[2:3]
1301; GFX10-GISEL-NEXT:    s_waitcnt vmcnt(0)
1302; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v1, v0
1303; GFX10-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
1304; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v0, v1, 32, vcc_lo
1305; GFX10-GISEL-NEXT:    v_mov_b32_e32 v1, 0
1306; GFX10-GISEL-NEXT:    v_cmp_ne_u32_e32 vcc_lo, 32, v0
1307; GFX10-GISEL-NEXT:    v_cndmask_b32_e32 v0, -1, v0, vcc_lo
1308; GFX10-GISEL-NEXT:    global_store_dword v1, v0, s[0:1]
1309; GFX10-GISEL-NEXT:    s_endpgm
1310  %tid = call i32 @llvm.amdgcn.workitem.id.x()
1311  %in.gep = getelementptr i32, i32 addrspace(1)* %valptr, i32 %tid
1312  %val = load i32, i32 addrspace(1)* %in.gep
1313  %cttz = call i32 @llvm.cttz.i32(i32 %val, i1 false) nounwind readnone
1314  %cmp = icmp ne i32 %cttz, 32
1315  %sel = select i1 %cmp, i32 %cttz, i32 -1
1316  store i32 %sel, i32 addrspace(1)* %out
1317  ret void
1318}
1319
1320 define amdgpu_kernel void @v_cttz_i8_sel_eq_neg1(i8 addrspace(1)* noalias %out, i8 addrspace(1)* noalias %valptr) nounwind {
1321; SI-LABEL: v_cttz_i8_sel_eq_neg1:
1322; SI:       ; %bb.0:
1323; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
1324; SI-NEXT:    s_mov_b32 s3, 0xf000
1325; SI-NEXT:    v_mov_b32_e32 v1, 0
1326; SI-NEXT:    s_mov_b32 s6, 0
1327; SI-NEXT:    s_mov_b32 s7, s3
1328; SI-NEXT:    s_waitcnt lgkmcnt(0)
1329; SI-NEXT:    buffer_load_ubyte v0, v[0:1], s[4:7], 0 addr64
1330; SI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
1331; SI-NEXT:    s_mov_b32 s2, -1
1332; SI-NEXT:    s_waitcnt vmcnt(0)
1333; SI-NEXT:    v_ffbl_b32_e32 v0, v0
1334; SI-NEXT:    s_waitcnt lgkmcnt(0)
1335; SI-NEXT:    buffer_store_byte v0, off, s[0:3], 0
1336; SI-NEXT:    s_endpgm
1337;
1338; VI-LABEL: v_cttz_i8_sel_eq_neg1:
1339; VI:       ; %bb.0:
1340; VI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
1341; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x2c
1342; VI-NEXT:    s_mov_b32 s7, 0xf000
1343; VI-NEXT:    s_mov_b32 s6, -1
1344; VI-NEXT:    s_waitcnt lgkmcnt(0)
1345; VI-NEXT:    v_mov_b32_e32 v1, s1
1346; VI-NEXT:    v_add_u32_e32 v0, vcc, s0, v0
1347; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
1348; VI-NEXT:    flat_load_ubyte v0, v[0:1]
1349; VI-NEXT:    s_waitcnt vmcnt(0)
1350; VI-NEXT:    v_ffbl_b32_e32 v0, v0
1351; VI-NEXT:    buffer_store_byte v0, off, s[4:7], 0
1352; VI-NEXT:    s_endpgm
1353;
1354; EG-LABEL: v_cttz_i8_sel_eq_neg1:
1355; EG:       ; %bb.0:
1356; EG-NEXT:    ALU 0, @8, KC0[CB0:0-32], KC1[]
1357; EG-NEXT:    TEX 0 @6
1358; EG-NEXT:    ALU 12, @9, KC0[CB0:0-32], KC1[]
1359; EG-NEXT:    MEM_RAT MSKOR T0.XW, T1.X
1360; EG-NEXT:    CF_END
1361; EG-NEXT:    PAD
1362; EG-NEXT:    Fetch clause starting at 6:
1363; EG-NEXT:     VTX_READ_8 T0.X, T0.X, 0, #1
1364; EG-NEXT:    ALU clause starting at 8:
1365; EG-NEXT:     ADD_INT * T0.X, KC0[2].Z, T0.X,
1366; EG-NEXT:    ALU clause starting at 9:
1367; EG-NEXT:     FFBL_INT T0.W, T0.X,
1368; EG-NEXT:     AND_INT * T1.W, KC0[2].Y, literal.x,
1369; EG-NEXT:    3(4.203895e-45), 0(0.000000e+00)
1370; EG-NEXT:     AND_INT T0.W, PV.W, literal.x,
1371; EG-NEXT:     LSHL * T1.W, PS, literal.y,
1372; EG-NEXT:    255(3.573311e-43), 3(4.203895e-45)
1373; EG-NEXT:     LSHL T0.X, PV.W, PS,
1374; EG-NEXT:     LSHL * T0.W, literal.x, PS,
1375; EG-NEXT:    255(3.573311e-43), 0(0.000000e+00)
1376; EG-NEXT:     MOV T0.Y, 0.0,
1377; EG-NEXT:     MOV * T0.Z, 0.0,
1378; EG-NEXT:     LSHR * T1.X, KC0[2].Y, literal.x,
1379; EG-NEXT:    2(2.802597e-45), 0(0.000000e+00)
1380;
1381; GFX10-LABEL: v_cttz_i8_sel_eq_neg1:
1382; GFX10:       ; %bb.0:
1383; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
1384; GFX10-NEXT:    v_mov_b32_e32 v1, 0
1385; GFX10-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
1386; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
1387; GFX10-NEXT:    global_load_ubyte v0, v0, s[2:3]
1388; GFX10-NEXT:    s_waitcnt vmcnt(0)
1389; GFX10-NEXT:    v_ffbl_b32_e32 v0, v0
1390; GFX10-NEXT:    global_store_byte v1, v0, s[0:1]
1391; GFX10-NEXT:    s_endpgm
1392;
1393; GFX10-GISEL-LABEL: v_cttz_i8_sel_eq_neg1:
1394; GFX10-GISEL:       ; %bb.0:
1395; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
1396; GFX10-GISEL-NEXT:    v_ashrrev_i32_e32 v3, 31, v0
1397; GFX10-GISEL-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
1398; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
1399; GFX10-GISEL-NEXT:    v_mov_b32_e32 v1, s2
1400; GFX10-GISEL-NEXT:    v_mov_b32_e32 v2, s3
1401; GFX10-GISEL-NEXT:    v_add_co_u32 v0, vcc_lo, v1, v0
1402; GFX10-GISEL-NEXT:    v_add_co_ci_u32_e32 v1, vcc_lo, v2, v3, vcc_lo
1403; GFX10-GISEL-NEXT:    global_load_ubyte v0, v[0:1], off
1404; GFX10-GISEL-NEXT:    s_waitcnt vmcnt(0)
1405; GFX10-GISEL-NEXT:    v_and_b32_e32 v0, 0xff, v0
1406; GFX10-GISEL-NEXT:    v_or_b32_e32 v1, 0x100, v0
1407; GFX10-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
1408; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v1, v1
1409; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v0, v1, -1, vcc_lo
1410; GFX10-GISEL-NEXT:    v_mov_b32_e32 v1, 0
1411; GFX10-GISEL-NEXT:    global_store_byte v1, v0, s[0:1]
1412; GFX10-GISEL-NEXT:    s_endpgm
1413  %tid = call i32 @llvm.amdgcn.workitem.id.x()
1414  %valptr.gep = getelementptr i8, i8 addrspace(1)* %valptr, i32 %tid
1415  %val = load i8, i8 addrspace(1)* %valptr.gep
1416  %cttz = call i8 @llvm.cttz.i8(i8 %val, i1 false) nounwind readnone
1417  %cmp = icmp eq i8 %val, 0
1418  %sel = select i1 %cmp, i8 -1, i8 %cttz
1419  store i8 %sel, i8 addrspace(1)* %out
1420  ret void
1421}
1422
1423 define amdgpu_kernel void @v_cttz_i16_sel_eq_neg1(i16 addrspace(1)* noalias %out, i16 addrspace(1)* noalias %valptr) nounwind {
1424; SI-LABEL: v_cttz_i16_sel_eq_neg1:
1425; SI:       ; %bb.0:
1426; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
1427; SI-NEXT:    s_mov_b32 s3, 0xf000
1428; SI-NEXT:    s_mov_b32 s2, -1
1429; SI-NEXT:    s_mov_b32 s6, s2
1430; SI-NEXT:    s_mov_b32 s7, s3
1431; SI-NEXT:    s_waitcnt lgkmcnt(0)
1432; SI-NEXT:    buffer_load_ushort v0, off, s[4:7], 0
1433; SI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
1434; SI-NEXT:    s_waitcnt vmcnt(0)
1435; SI-NEXT:    v_ffbl_b32_e32 v0, v0
1436; SI-NEXT:    s_waitcnt lgkmcnt(0)
1437; SI-NEXT:    buffer_store_short v0, off, s[0:3], 0
1438; SI-NEXT:    s_endpgm
1439;
1440; VI-LABEL: v_cttz_i16_sel_eq_neg1:
1441; VI:       ; %bb.0:
1442; VI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
1443; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x2c
1444; VI-NEXT:    s_mov_b32 s7, 0xf000
1445; VI-NEXT:    s_mov_b32 s6, -1
1446; VI-NEXT:    s_mov_b32 s2, s6
1447; VI-NEXT:    s_mov_b32 s3, s7
1448; VI-NEXT:    s_waitcnt lgkmcnt(0)
1449; VI-NEXT:    buffer_load_ushort v0, off, s[0:3], 0
1450; VI-NEXT:    v_mov_b32_e32 v1, 0xffff
1451; VI-NEXT:    s_waitcnt vmcnt(0)
1452; VI-NEXT:    v_or_b32_e32 v2, 0x10000, v0
1453; VI-NEXT:    v_ffbl_b32_e32 v2, v2
1454; VI-NEXT:    v_min_u32_e32 v2, 32, v2
1455; VI-NEXT:    v_cmp_ne_u16_e32 vcc, 0, v0
1456; VI-NEXT:    v_cndmask_b32_e32 v0, v1, v2, vcc
1457; VI-NEXT:    buffer_store_short v0, off, s[4:7], 0
1458; VI-NEXT:    s_endpgm
1459;
1460; EG-LABEL: v_cttz_i16_sel_eq_neg1:
1461; EG:       ; %bb.0:
1462; EG-NEXT:    ALU 0, @8, KC0[CB0:0-32], KC1[]
1463; EG-NEXT:    TEX 0 @6
1464; EG-NEXT:    ALU 12, @9, KC0[CB0:0-32], KC1[]
1465; EG-NEXT:    MEM_RAT MSKOR T0.XW, T1.X
1466; EG-NEXT:    CF_END
1467; EG-NEXT:    PAD
1468; EG-NEXT:    Fetch clause starting at 6:
1469; EG-NEXT:     VTX_READ_16 T0.X, T0.X, 0, #1
1470; EG-NEXT:    ALU clause starting at 8:
1471; EG-NEXT:     MOV * T0.X, KC0[2].Z,
1472; EG-NEXT:    ALU clause starting at 9:
1473; EG-NEXT:     FFBL_INT T0.W, T0.X,
1474; EG-NEXT:     AND_INT * T1.W, KC0[2].Y, literal.x,
1475; EG-NEXT:    3(4.203895e-45), 0(0.000000e+00)
1476; EG-NEXT:     AND_INT T0.W, PV.W, literal.x,
1477; EG-NEXT:     LSHL * T1.W, PS, literal.y,
1478; EG-NEXT:    65535(9.183409e-41), 3(4.203895e-45)
1479; EG-NEXT:     LSHL T0.X, PV.W, PS,
1480; EG-NEXT:     LSHL * T0.W, literal.x, PS,
1481; EG-NEXT:    65535(9.183409e-41), 0(0.000000e+00)
1482; EG-NEXT:     MOV T0.Y, 0.0,
1483; EG-NEXT:     MOV * T0.Z, 0.0,
1484; EG-NEXT:     LSHR * T1.X, KC0[2].Y, literal.x,
1485; EG-NEXT:    2(2.802597e-45), 0(0.000000e+00)
1486;
1487; GFX10-LABEL: v_cttz_i16_sel_eq_neg1:
1488; GFX10:       ; %bb.0:
1489; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
1490; GFX10-NEXT:    v_mov_b32_e32 v0, 0
1491; GFX10-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
1492; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
1493; GFX10-NEXT:    global_load_ushort v1, v0, s[2:3]
1494; GFX10-NEXT:    s_waitcnt vmcnt(0)
1495; GFX10-NEXT:    v_or_b32_e32 v2, 0x10000, v1
1496; GFX10-NEXT:    v_cmp_ne_u16_e32 vcc_lo, 0, v1
1497; GFX10-NEXT:    v_ffbl_b32_e32 v2, v2
1498; GFX10-NEXT:    v_min_u32_e32 v2, 32, v2
1499; GFX10-NEXT:    v_cndmask_b32_e32 v1, 0xffff, v2, vcc_lo
1500; GFX10-NEXT:    global_store_short v0, v1, s[0:1]
1501; GFX10-NEXT:    s_endpgm
1502;
1503; GFX10-GISEL-LABEL: v_cttz_i16_sel_eq_neg1:
1504; GFX10-GISEL:       ; %bb.0:
1505; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
1506; GFX10-GISEL-NEXT:    v_mov_b32_e32 v0, 0
1507; GFX10-GISEL-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
1508; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
1509; GFX10-GISEL-NEXT:    global_load_ushort v1, v0, s[2:3]
1510; GFX10-GISEL-NEXT:    s_waitcnt_depctr 0xffe3
1511; GFX10-GISEL-NEXT:    s_mov_b32 s2, 0xffff
1512; GFX10-GISEL-NEXT:    s_waitcnt vmcnt(0)
1513; GFX10-GISEL-NEXT:    v_or_b32_e32 v2, 0x10000, v1
1514; GFX10-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v1
1515; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v2, v2
1516; GFX10-GISEL-NEXT:    v_and_b32_e32 v2, s2, v2
1517; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v1, v2, s2, vcc_lo
1518; GFX10-GISEL-NEXT:    global_store_short v0, v1, s[0:1]
1519; GFX10-GISEL-NEXT:    s_endpgm
1520  %val = load i16, i16 addrspace(1)* %valptr
1521  %cttz = call i16 @llvm.cttz.i16(i16 %val, i1 false) nounwind readnone
1522  %cmp = icmp eq i16 %val, 0
1523  %sel = select i1 %cmp, i16 -1, i16 %cttz
1524  store i16 %sel, i16 addrspace(1)* %out
1525  ret void
1526}
1527
1528; FIXME: Need to handle non-uniform case for function below (load without gep).
1529define amdgpu_kernel void @v_cttz_i7_sel_eq_neg1(i7 addrspace(1)* noalias %out, i7 addrspace(1)* noalias %valptr) nounwind {
1530; SI-LABEL: v_cttz_i7_sel_eq_neg1:
1531; SI:       ; %bb.0:
1532; SI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0xb
1533; SI-NEXT:    s_mov_b32 s3, 0xf000
1534; SI-NEXT:    v_mov_b32_e32 v1, 0
1535; SI-NEXT:    s_mov_b32 s6, 0
1536; SI-NEXT:    s_mov_b32 s7, s3
1537; SI-NEXT:    s_waitcnt lgkmcnt(0)
1538; SI-NEXT:    buffer_load_ubyte v0, v[0:1], s[4:7], 0 addr64
1539; SI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x9
1540; SI-NEXT:    s_mov_b32 s2, -1
1541; SI-NEXT:    s_waitcnt vmcnt(0)
1542; SI-NEXT:    v_ffbl_b32_e32 v0, v0
1543; SI-NEXT:    v_and_b32_e32 v0, 0x7f, v0
1544; SI-NEXT:    s_waitcnt lgkmcnt(0)
1545; SI-NEXT:    buffer_store_byte v0, off, s[0:3], 0
1546; SI-NEXT:    s_endpgm
1547;
1548; VI-LABEL: v_cttz_i7_sel_eq_neg1:
1549; VI:       ; %bb.0:
1550; VI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
1551; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x2c
1552; VI-NEXT:    s_mov_b32 s7, 0xf000
1553; VI-NEXT:    s_mov_b32 s6, -1
1554; VI-NEXT:    s_waitcnt lgkmcnt(0)
1555; VI-NEXT:    v_mov_b32_e32 v1, s1
1556; VI-NEXT:    v_add_u32_e32 v0, vcc, s0, v0
1557; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
1558; VI-NEXT:    flat_load_ubyte v0, v[0:1]
1559; VI-NEXT:    s_waitcnt vmcnt(0)
1560; VI-NEXT:    v_ffbl_b32_e32 v0, v0
1561; VI-NEXT:    v_and_b32_e32 v0, 0x7f, v0
1562; VI-NEXT:    buffer_store_byte v0, off, s[4:7], 0
1563; VI-NEXT:    s_endpgm
1564;
1565; EG-LABEL: v_cttz_i7_sel_eq_neg1:
1566; EG:       ; %bb.0:
1567; EG-NEXT:    ALU 0, @8, KC0[CB0:0-32], KC1[]
1568; EG-NEXT:    TEX 0 @6
1569; EG-NEXT:    ALU 12, @9, KC0[CB0:0-32], KC1[]
1570; EG-NEXT:    MEM_RAT MSKOR T0.XW, T1.X
1571; EG-NEXT:    CF_END
1572; EG-NEXT:    PAD
1573; EG-NEXT:    Fetch clause starting at 6:
1574; EG-NEXT:     VTX_READ_8 T0.X, T0.X, 0, #1
1575; EG-NEXT:    ALU clause starting at 8:
1576; EG-NEXT:     ADD_INT * T0.X, KC0[2].Z, T0.X,
1577; EG-NEXT:    ALU clause starting at 9:
1578; EG-NEXT:     FFBL_INT T0.W, T0.X,
1579; EG-NEXT:     AND_INT * T1.W, KC0[2].Y, literal.x,
1580; EG-NEXT:    3(4.203895e-45), 0(0.000000e+00)
1581; EG-NEXT:     AND_INT T0.W, PV.W, literal.x,
1582; EG-NEXT:     LSHL * T1.W, PS, literal.y,
1583; EG-NEXT:    127(1.779649e-43), 3(4.203895e-45)
1584; EG-NEXT:     LSHL T0.X, PV.W, PS,
1585; EG-NEXT:     LSHL * T0.W, literal.x, PS,
1586; EG-NEXT:    255(3.573311e-43), 0(0.000000e+00)
1587; EG-NEXT:     MOV T0.Y, 0.0,
1588; EG-NEXT:     MOV * T0.Z, 0.0,
1589; EG-NEXT:     LSHR * T1.X, KC0[2].Y, literal.x,
1590; EG-NEXT:    2(2.802597e-45), 0(0.000000e+00)
1591;
1592; GFX10-LABEL: v_cttz_i7_sel_eq_neg1:
1593; GFX10:       ; %bb.0:
1594; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
1595; GFX10-NEXT:    v_mov_b32_e32 v1, 0
1596; GFX10-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
1597; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
1598; GFX10-NEXT:    global_load_ubyte v0, v0, s[2:3]
1599; GFX10-NEXT:    s_waitcnt vmcnt(0)
1600; GFX10-NEXT:    v_ffbl_b32_e32 v0, v0
1601; GFX10-NEXT:    v_and_b32_e32 v0, 0x7f, v0
1602; GFX10-NEXT:    global_store_byte v1, v0, s[0:1]
1603; GFX10-NEXT:    s_endpgm
1604;
1605; GFX10-GISEL-LABEL: v_cttz_i7_sel_eq_neg1:
1606; GFX10-GISEL:       ; %bb.0:
1607; GFX10-GISEL-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
1608; GFX10-GISEL-NEXT:    v_ashrrev_i32_e32 v3, 31, v0
1609; GFX10-GISEL-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
1610; GFX10-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
1611; GFX10-GISEL-NEXT:    v_mov_b32_e32 v1, s2
1612; GFX10-GISEL-NEXT:    v_mov_b32_e32 v2, s3
1613; GFX10-GISEL-NEXT:    s_movk_i32 s2, 0x7f
1614; GFX10-GISEL-NEXT:    v_add_co_u32 v0, vcc_lo, v1, v0
1615; GFX10-GISEL-NEXT:    v_add_co_ci_u32_e32 v1, vcc_lo, v2, v3, vcc_lo
1616; GFX10-GISEL-NEXT:    global_load_ubyte v0, v[0:1], off
1617; GFX10-GISEL-NEXT:    s_waitcnt vmcnt(0)
1618; GFX10-GISEL-NEXT:    v_and_or_b32 v1, v0, s2, 0x80
1619; GFX10-GISEL-NEXT:    v_and_b32_e32 v0, s2, v0
1620; GFX10-GISEL-NEXT:    v_ffbl_b32_e32 v1, v1
1621; GFX10-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc_lo, 0, v0
1622; GFX10-GISEL-NEXT:    v_cndmask_b32_e64 v0, v1, 0x7f, vcc_lo
1623; GFX10-GISEL-NEXT:    v_mov_b32_e32 v1, 0
1624; GFX10-GISEL-NEXT:    v_and_b32_e32 v0, s2, v0
1625; GFX10-GISEL-NEXT:    global_store_byte v1, v0, s[0:1]
1626; GFX10-GISEL-NEXT:    s_endpgm
1627  %tid = call i32 @llvm.amdgcn.workitem.id.x()
1628  %valptr.gep = getelementptr i7, i7 addrspace(1)* %valptr, i32 %tid
1629  %val = load i7, i7 addrspace(1)* %valptr.gep
1630  %cttz = call i7 @llvm.cttz.i7(i7 %val, i1 false) nounwind readnone
1631  %cmp = icmp eq i7 %val, 0
1632  %sel = select i1 %cmp, i7 -1, i7 %cttz
1633  store i7 %sel, i7 addrspace(1)* %out
1634  ret void
1635}
1636