1; RUN: llc -verify-machineinstrs -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -enable-amdgpu-aa=0 -mattr=+flat-for-global,-fp64-fp16-denormals < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX9,GFX89 %s
2; RUN: llc -verify-machineinstrs -mtriple=amdgcn-amd-amdhsa -mcpu=fiji -enable-amdgpu-aa=0 -mattr=+flat-for-global < %s | FileCheck -enable-var-scope -check-prefixes=GCN,CIVI,VI,GFX89 %s
3; RUN: llc -verify-machineinstrs -mtriple=amdgcn-amd-amdhsa -mcpu=hawaii -enable-amdgpu-aa=0 -mattr=+flat-for-global < %s | FileCheck -enable-var-scope -check-prefixes=GCN,CIVI,CI %s
4
5; GCN-LABEL: {{^}}s_insertelement_v2i16_0:
6; GCN: s_load_dword [[VEC:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0x0
7
8; CIVI: s_and_b32 [[ELT1:s[0-9]+]], [[VEC]], 0xffff0000{{$}}
9; CIVI: s_or_b32 s{{[0-9]+}}, [[ELT1]], 0x3e7{{$}}
10
11; GFX9-NOT: lshr
12; GFX9: s_pack_lh_b32_b16 s{{[0-9]+}}, 0x3e7, [[VEC]]
13define amdgpu_kernel void @s_insertelement_v2i16_0(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(4)* %vec.ptr) #0 {
14  %vec = load <2 x i16>, <2 x i16> addrspace(4)* %vec.ptr
15  %vecins = insertelement <2 x i16> %vec, i16 999, i32 0
16  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out
17  ret void
18}
19
20; GCN-LABEL: {{^}}s_insertelement_v2i16_0_reg:
21; GCN-DAG: s_load_dword [[ELT_LOAD:s[0-9]+]], s[4:5],
22; GCN-DAG: s_load_dword [[VEC:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0x0
23
24; CIVI-DAG: s_and_b32 [[ELT0:s[0-9]+]], [[ELT_LOAD]], 0xffff{{$}}
25; CIVI-DAG: s_and_b32 [[ELT1:s[0-9]+]], [[VEC]], 0xffff0000{{$}}
26; CIVI: s_or_b32 s{{[0-9]+}}, [[ELT0]], [[ELT1]]
27
28; GFX9-NOT: [[ELT0]]
29; GFX9-NOT: [[VEC]]
30; GFX9: s_pack_lh_b32_b16 s{{[0-9]+}}, [[ELT_LOAD]], [[VEC]]
31define amdgpu_kernel void @s_insertelement_v2i16_0_reg(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(4)* %vec.ptr, [8 x i32], i16 %elt) #0 {
32  %vec = load <2 x i16>, <2 x i16> addrspace(4)* %vec.ptr
33  %vecins = insertelement <2 x i16> %vec, i16 %elt, i32 0
34  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out
35  ret void
36}
37
38; GCN-LABEL: {{^}}s_insertelement_v2i16_0_multi_use_hi_reg:
39; GCN-DAG: s_load_dword [[ELT_LOAD:s[0-9]+]], s[4:5],
40; GCN-DAG: s_load_dword [[VEC:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0x0
41
42; CI-DAG: s_and_b32 [[ELT0_MASKED:s[0-9]+]], [[ELT_LOAD]], 0xffff{{$}}
43; CI: s_lshr_b32 [[SHR:s[0-9]+]], [[VEC]], 16
44; CI: s_lshl_b32 [[ELT1:s[0-9]+]], [[SHR]], 16
45; CI-DAG: s_or_b32 s{{[0-9]+}}, [[ELT0_MASKED]], [[ELT1]]
46; CI-DAG: ; use [[SHR]]
47
48
49; FIXME: Should be able to void mask of upper bits
50; VI-DAG: s_and_b32 [[ELT_MASKED:s[0-9]+]], [[ELT_LOAD]], 0xffff{{$}}
51; VI-DAG: s_and_b32 [[VEC_HIMASK:s[0-9]+]], [[VEC]], 0xffff0000{{$}}
52; VI-DAG: s_or_b32 [[OR:s[0-9]+]], [[ELT_MASKED]], [[VEC_HIMASK]]
53; VI-DAG: s_lshr_b32 [[SHR:s[0-9]+]], [[VEC]], 16
54
55; VI-DAG: ; use [[SHR]]
56
57
58; GFX9: s_lshr_b32 [[ELT1:s[0-9]+]], [[VEC]], 16
59; GFX9-DAG: s_pack_ll_b32_b16 s{{[0-9]+}}, [[ELT_LOAD]], [[ELT1]]
60; GFX9-DAG: ; use [[ELT1]]
61define amdgpu_kernel void @s_insertelement_v2i16_0_multi_use_hi_reg(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(4)* %vec.ptr, [8 x i32], i16 %elt) #0 {
62  %vec = load <2 x i16>, <2 x i16> addrspace(4)* %vec.ptr
63  %elt1 = extractelement <2 x i16> %vec, i32 1
64  %vecins = insertelement <2 x i16> %vec, i16 %elt, i32 0
65  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out
66  %use1 = zext i16 %elt1 to i32
67  call void asm sideeffect "; use $0", "s"(i32 %use1) #0
68  ret void
69}
70
71; GCN-LABEL: {{^}}s_insertelement_v2i16_0_reghi:
72; GCN-DAG: s_load_dword [[ELT_ARG:s[0-9]+]], s[4:5],
73; GCN-DAG: s_load_dword [[VEC:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0x0
74
75; CIVI: s_lshr_b32 [[ELT_HI:s[0-9]+]], [[ELT_ARG]], 16
76; CIVI-DAG: s_and_b32 [[ELT1:s[0-9]+]], [[VEC]], 0xffff0000{{$}}
77; CIVI: s_or_b32 s{{[0-9]+}}, [[ELT_HI]], [[ELT1]]
78
79; GFX9-NOT: [[ELT0]]
80; GFX9-NOT: [[VEC]]
81; GFX9: s_pack_hh_b32_b16 s{{[0-9]+}}, [[ELT_ARG]], [[VEC]]
82define amdgpu_kernel void @s_insertelement_v2i16_0_reghi(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(4)* %vec.ptr, [8 x i32], i32 %elt.arg) #0 {
83  %vec = load <2 x i16>, <2 x i16> addrspace(4)* %vec.ptr
84  %elt.hi = lshr i32 %elt.arg, 16
85  %elt = trunc i32 %elt.hi to i16
86  %vecins = insertelement <2 x i16> %vec, i16 %elt, i32 0
87  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out
88  ret void
89}
90
91; GCN-LABEL: {{^}}s_insertelement_v2i16_0_reghi_multi_use_1:
92; GCN: s_load_dword [[ELT_ARG:s[0-9]+]],
93; GCN: s_load_dword [[VEC:s[0-9]+]],
94
95; CIVI-DAG: s_lshr_b32 [[ELT1:s[0-9]+]], [[ELT_ARG]], 16
96; CIVI-DAG: s_and_b32 [[ELT0:s[0-9]+]], [[VEC]], 0xffff0000{{$}}
97; CIVI: s_or_b32 s{{[0-9]+}}, [[ELT1]], [[ELT0]]
98
99; GFX9: s_lshr_b32 [[ELT1:s[0-9]+]], [[ELT_ARG]], 16
100; GFX9: s_pack_lh_b32_b16 s{{[0-9]+}}, [[ELT1]], [[VEC]]
101; GFX9: ; use [[ELT1]]
102define amdgpu_kernel void @s_insertelement_v2i16_0_reghi_multi_use_1(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(4)* %vec.ptr, i32 %elt.arg) #0 {
103  %vec = load <2 x i16>, <2 x i16> addrspace(4)* %vec.ptr
104  %elt.hi = lshr i32 %elt.arg, 16
105  %elt = trunc i32 %elt.hi to i16
106  %vecins = insertelement <2 x i16> %vec, i16 %elt, i32 0
107  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out
108  %use1 = zext i16 %elt to i32
109  call void asm sideeffect "; use $0", "s"(i32 %use1) #0
110  ret void
111}
112
113; GCN-LABEL: {{^}}s_insertelement_v2i16_0_reghi_both_multi_use_1:
114; GCN: s_load_dword [[ELT_ARG:s[0-9]+]],
115; GCN: s_load_dword [[VEC:s[0-9]+]],
116
117; CI-DAG: s_lshr_b32 [[ELT_HI:s[0-9]+]], [[ELT_ARG]], 16
118; CI-DAG: s_lshr_b32 [[SHR:s[0-9]+]], [[VEC]], 16
119; CI-DAG: s_lshl_b32 [[VEC_HI:s[0-9]+]], [[SHR]], 16
120; CI: s_or_b32 s{{[0-9]+}}, [[ELT_HI]], [[VEC_HI]]
121
122
123; VI-DAG: s_lshr_b32 [[ELT_HI:s[0-9]+]], [[ELT_ARG]], 16
124; VI-DAG: s_lshr_b32 [[VEC_HI:s[0-9]+]], [[VEC]], 16
125; VI: s_and_b32 [[MASK_HI:s[0-9]+]], [[VEC]], 0xffff0000
126; VI: s_or_b32 s{{[0-9]+}}, [[ELT_HI]], [[MASK_HI]]
127
128; GFX9-DAG: s_lshr_b32 [[ELT_HI:s[0-9]+]], [[ELT_ARG]], 16
129; GFX9-DAG: s_lshr_b32 [[VEC_HI:s[0-9]+]], [[VEC]], 16
130; GFX9: s_pack_ll_b32_b16 s{{[0-9]+}}, [[ELT_HI]], [[VEC_HI]]
131; GFX9: ; use [[ELT_HI]]
132; GFX9: ; use [[VEC_HI]]
133define amdgpu_kernel void @s_insertelement_v2i16_0_reghi_both_multi_use_1(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(4)* %vec.ptr, i32 %elt.arg) #0 {
134  %vec = load <2 x i16>, <2 x i16> addrspace(4)* %vec.ptr
135  %elt.hi = lshr i32 %elt.arg, 16
136  %elt = trunc i32 %elt.hi to i16
137  %vec.hi = extractelement <2 x i16> %vec, i32 1
138  %vecins = insertelement <2 x i16> %vec, i16 %elt, i32 0
139  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out
140  %use1 = zext i16 %elt to i32
141  %vec.hi.use1 = zext i16 %vec.hi to i32
142
143  call void asm sideeffect "; use $0", "s"(i32 %use1) #0
144  call void asm sideeffect "; use $0", "s"(i32 %vec.hi.use1) #0
145  ret void
146}
147
148; GCN-LABEL: {{^}}s_insertelement_v2i16_1:
149; GCN: s_load_dword [[VEC:s[0-9]+]]
150
151; GCN-NOT: s_lshr
152
153; CIVI: s_and_b32 [[ELT0:s[0-9]+]], [[VEC]], 0xffff{{$}}
154; CIVI: s_or_b32 [[INS:s[0-9]+]], [[ELT0]], 0x3e70000
155
156; GFX9: s_pack_ll_b32_b16 s{{[0-9]+}}, [[VEC]], 0x3e7
157define amdgpu_kernel void @s_insertelement_v2i16_1(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(4)* %vec.ptr) #0 {
158  %vec = load <2 x i16>, <2 x i16> addrspace(4)* %vec.ptr
159  %vecins = insertelement <2 x i16> %vec, i16 999, i32 1
160  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out
161  ret void
162}
163
164; GCN-LABEL: {{^}}s_insertelement_v2i16_1_reg:
165; GCN-DAG: s_load_dword [[ELT1_LOAD:s[0-9]+]], s[4:5],
166; GCN-DAG: s_load_dword [[VEC:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0x0
167
168; CIVI: s_lshl_b32 [[ELT1:s[0-9]+]], [[ELT1_LOAD]], 16
169; CIVI: s_and_b32 [[ELT0:s[0-9]+]], [[VEC]], 0xffff{{$}}
170; CIVI: s_or_b32 s{{[0-9]+}}, [[ELT0]], [[ELT1]]
171
172; GCN-NOT: shlr
173; GFX9: s_pack_ll_b32_b16 s{{[0-9]+}}, [[VEC]], [[ELT1_LOAD]]
174define amdgpu_kernel void @s_insertelement_v2i16_1_reg(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(4)* %vec.ptr, [8 x i32], i16 %elt) #0 {
175  %vec = load <2 x i16>, <2 x i16> addrspace(4)* %vec.ptr
176  %vecins = insertelement <2 x i16> %vec, i16 %elt, i32 1
177  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out
178  ret void
179}
180
181; GCN-LABEL: {{^}}s_insertelement_v2f16_0:
182; GCN: s_load_dword [[VEC:s[0-9]+]]
183; CIVI: s_and_b32 [[ELT1:s[0-9]+]], [[VEC:s[0-9]+]], 0xffff0000
184; CIVI: s_or_b32 s{{[0-9]+}}, [[ELT1]], 0x4500
185
186; GFX9: s_lshr_b32 [[ELT1:s[0-9]+]], [[VEC]], 16
187; GFX9: s_pack_ll_b32_b16 s{{[0-9]+}}, 0x4500, [[ELT1]]
188define amdgpu_kernel void @s_insertelement_v2f16_0(<2 x half> addrspace(1)* %out, <2 x half> addrspace(4)* %vec.ptr) #0 {
189  %vec = load <2 x half>, <2 x half> addrspace(4)* %vec.ptr
190  %vecins = insertelement <2 x half> %vec, half 5.000000e+00, i32 0
191  store <2 x half> %vecins, <2 x half> addrspace(1)* %out
192  ret void
193}
194
195; GCN-LABEL: {{^}}s_insertelement_v2f16_1:
196; GCN: s_load_dword [[VEC:s[0-9]+]]
197; GCN-NOT: s_lshr
198
199; CIVI: s_and_b32 [[ELT0:s[0-9]+]], [[VEC]], 0xffff{{$}}
200; CIVI: s_or_b32 [[INS:s[0-9]+]], [[ELT0]], 0x45000000
201
202; GFX9: s_pack_ll_b32_b16 s{{[0-9]+}}, [[VEC]], 0x4500
203define amdgpu_kernel void @s_insertelement_v2f16_1(<2 x half> addrspace(1)* %out, <2 x half> addrspace(4)* %vec.ptr) #0 {
204  %vec = load <2 x half>, <2 x half> addrspace(4)* %vec.ptr
205  %vecins = insertelement <2 x half> %vec, half 5.000000e+00, i32 1
206  store <2 x half> %vecins, <2 x half> addrspace(1)* %out
207  ret void
208}
209
210; GCN-LABEL: {{^}}v_insertelement_v2i16_0:
211; GCN-DAG: {{flat|global}}_load_dword [[VEC:v[0-9]+]]
212; CIVI: v_and_b32_e32 [[ELT1:v[0-9]+]], 0xffff0000, [[VEC]]
213; CIVI: v_or_b32_e32 [[RES:v[0-9]+]], 0x3e7, [[ELT1]]
214
215; GFX9-DAG: s_movk_i32 [[ELT0:s[0-9]+]], 0x3e7{{$}}
216; GFX9-DAG: v_mov_b32_e32 [[MASK:v[0-9]+]], 0xffff{{$}}
217; GFX9: v_bfi_b32 [[RES:v[0-9]+]], [[MASK]], [[ELT0]], [[VEC]]
218; GCN: {{flat|global}}_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RES]]
219define amdgpu_kernel void @v_insertelement_v2i16_0(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in) #0 {
220  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
221  %tid.ext = sext i32 %tid to i64
222  %in.gep = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in, i64 %tid.ext
223  %out.gep = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %out, i64 %tid.ext
224  %vec = load <2 x i16>, <2 x i16> addrspace(1)* %in.gep
225  %vecins = insertelement <2 x i16> %vec, i16 999, i32 0
226  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out.gep
227  ret void
228}
229
230; GCN-LABEL: {{^}}v_insertelement_v2i16_0_reghi:
231; GCN-DAG: {{flat|global}}_load_dword [[VEC:v[0-9]+]]
232; GCN-DAG: s_load_dword [[ELT0:s[0-9]+]]
233
234; CIVI-DAG: s_lshr_b32 [[ELT0_SHIFT:s[0-9]+]], [[ELT0]], 16
235; CIVI-DAG: v_and_b32_e32 [[ELT1:v[0-9]+]], 0xffff0000, [[VEC]]
236; CIVI: v_or_b32_e32 [[RES:v[0-9]+]], [[ELT0_SHIFT]], [[ELT1]]
237
238; GFX9-DAG: v_mov_b32_e32 [[MASK:v[0-9]+]], 0xffff0000{{$}}
239; GFX9-DAG: v_lshrrev_b32_e64 [[ELT0_SHIFT:v[0-9]+]], 16, [[ELT0]]
240; GFX9: v_and_or_b32 [[RES:v[0-9]+]], [[VEC]], [[MASK]], [[ELT0_SHIFT]]
241
242; GCN: {{flat|global}}_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RES]]
243define amdgpu_kernel void @v_insertelement_v2i16_0_reghi(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in, i32 %elt.arg) #0 {
244  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
245  %tid.ext = sext i32 %tid to i64
246  %in.gep = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in, i64 %tid.ext
247  %out.gep = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %out, i64 %tid.ext
248  %vec = load <2 x i16>, <2 x i16> addrspace(1)* %in.gep
249  %elt.hi = lshr i32 %elt.arg, 16
250  %elt = trunc i32 %elt.hi to i16
251  %vecins = insertelement <2 x i16> %vec, i16 %elt, i32 0
252  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out.gep
253  ret void
254}
255
256; GCN-LABEL: {{^}}v_insertelement_v2i16_0_inlineimm:
257; GCN-DAG: {{flat|global}}_load_dword [[VEC:v[0-9]+]]
258
259; CIVI: v_and_b32_e32 [[ELT1:v[0-9]+]], 0xffff0000, [[VEC]]
260; CIVI: v_or_b32_e32 [[RES:v[0-9]+]], 53, [[ELT1]]
261
262; GFX9-DAG: v_mov_b32_e32 [[MASK:v[0-9]+]], 0xffff{{$}}
263; GFX9: v_bfi_b32 [[RES:v[0-9]+]], [[MASK]], 53, [[VEC]]
264
265; GCN: {{flat|global}}_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RES]]
266define amdgpu_kernel void @v_insertelement_v2i16_0_inlineimm(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in) #0 {
267  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
268  %tid.ext = sext i32 %tid to i64
269  %in.gep = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in, i64 %tid.ext
270  %out.gep = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %out, i64 %tid.ext
271  %vec = load <2 x i16>, <2 x i16> addrspace(1)* %in.gep
272  %vecins = insertelement <2 x i16> %vec, i16 53, i32 0
273  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out.gep
274  ret void
275}
276
277; FIXME: fold lshl_or c0, c1, v0 -> or (c0 << c1), v0
278
279; GCN-LABEL: {{^}}v_insertelement_v2i16_1:
280; VI: v_mov_b32_e32 [[K:v[0-9]+]], 0x3e70000
281; GCN-DAG: {{flat|global}}_load_dword [[VEC:v[0-9]+]]
282
283; GFX9-DAG: s_movk_i32 [[K:s[0-9]+]], 0x3e7
284; GFX9-DAG: v_and_b32_e32 [[ELT0:v[0-9]+]], 0xffff, [[VEC]]
285; GFX9: v_lshl_or_b32 [[RES:v[0-9]+]], [[K]], 16, [[ELT0]]
286
287; CI: v_and_b32_e32 [[AND:v[0-9]+]], 0xffff, [[VEC]]
288; CI: v_or_b32_e32 [[RES:v[0-9]+]], 0x3e70000, [[AND]]
289; VI: v_or_b32_sdwa [[RES:v[0-9]+]], [[K]], [[VEC]] dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
290
291; GCN: {{flat|global}}_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RES]]
292define amdgpu_kernel void @v_insertelement_v2i16_1(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in) #0 {
293  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
294  %tid.ext = sext i32 %tid to i64
295  %in.gep = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in, i64 %tid.ext
296  %out.gep = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %out, i64 %tid.ext
297  %vec = load <2 x i16>, <2 x i16> addrspace(1)* %in.gep
298  %vecins = insertelement <2 x i16> %vec, i16 999, i32 1
299  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out.gep
300  ret void
301}
302
303; GCN-LABEL: {{^}}v_insertelement_v2i16_1_inlineimm:
304; VI: v_mov_b32_e32 [[K:v[0-9]+]], 0xfff10000
305; GCN: {{flat|global}}_load_dword [[VEC:v[0-9]+]]
306; CI:   v_and_b32_e32 [[ELT0:v[0-9]+]], 0xffff, [[VEC]]
307; GFX9: v_and_b32_e32 [[ELT0:v[0-9]+]], 0xffff, [[VEC]]
308; CI: v_or_b32_e32 [[RES:v[0-9]+]], 0xfff10000, [[ELT0]]
309; VI: v_or_b32_sdwa [[RES:v[0-9]+]], [[K]], [[VEC]] dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
310; GFX9: v_lshl_or_b32 [[RES:v[0-9]+]], -15, 16, [[ELT0]]
311; GCN: {{flat|global}}_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RES]]
312define amdgpu_kernel void @v_insertelement_v2i16_1_inlineimm(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in) #0 {
313  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
314  %tid.ext = sext i32 %tid to i64
315  %in.gep = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in, i64 %tid.ext
316  %out.gep = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %out, i64 %tid.ext
317  %vec = load <2 x i16>, <2 x i16> addrspace(1)* %in.gep
318  %vecins = insertelement <2 x i16> %vec, i16 -15, i32 1
319  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out.gep
320  ret void
321}
322
323; GCN-LABEL: {{^}}v_insertelement_v2f16_0:
324; GCN-DAG: {{flat|global}}_load_dword [[VEC:v[0-9]+]]
325
326; CIVI: v_and_b32_e32 [[ELT1:v[0-9]+]], 0xffff0000, [[VEC]]
327; CIVI: v_or_b32_e32 [[RES:v[0-9]+]], 0x4500, [[ELT1]]
328
329; GFX9-DAG: v_mov_b32_e32 [[ELT0:v[0-9]+]], 0x4500{{$}}
330; GFX9-DAG: v_lshrrev_b32_e32 [[ELT1:v[0-9]+]], 16, [[VEC]]
331; GFX9: v_lshl_or_b32 [[RES:v[0-9]+]], [[ELT1]], 16, [[ELT0]]
332
333; GCN: {{flat|global}}_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RES]]
334define amdgpu_kernel void @v_insertelement_v2f16_0(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %in) #0 {
335  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
336  %tid.ext = sext i32 %tid to i64
337  %in.gep = getelementptr inbounds <2 x half>, <2 x half> addrspace(1)* %in, i64 %tid.ext
338  %out.gep = getelementptr inbounds <2 x half>, <2 x half> addrspace(1)* %out, i64 %tid.ext
339  %vec = load <2 x half>, <2 x half> addrspace(1)* %in.gep
340  %vecins = insertelement <2 x half> %vec, half 5.000000e+00, i32 0
341  store <2 x half> %vecins, <2 x half> addrspace(1)* %out.gep
342  ret void
343}
344
345; GCN-LABEL: {{^}}v_insertelement_v2f16_0_inlineimm:
346; GCN: {{flat|global}}_load_dword [[VEC:v[0-9]+]]
347
348; CIVI: v_and_b32_e32 [[ELT1:v[0-9]+]], 0xffff0000, [[VEC]]
349; CIVI: v_or_b32_e32 [[RES:v[0-9]+]], 53, [[ELT1]]
350
351; GFX9: v_lshrrev_b32_e32 [[ELT1:v[0-9]+]], 16, [[VEC]]
352; GFX9: v_lshl_or_b32 [[RES:v[0-9]+]], [[ELT1]], 16, 53
353; GCN: {{flat|global}}_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RES]]
354define amdgpu_kernel void @v_insertelement_v2f16_0_inlineimm(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %in) #0 {
355  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
356  %tid.ext = sext i32 %tid to i64
357  %in.gep = getelementptr inbounds <2 x half>, <2 x half> addrspace(1)* %in, i64 %tid.ext
358  %out.gep = getelementptr inbounds <2 x half>, <2 x half> addrspace(1)* %out, i64 %tid.ext
359  %vec = load <2 x half>, <2 x half> addrspace(1)* %in.gep
360  %vecins = insertelement <2 x half> %vec, half 0xH0035, i32 0
361  store <2 x half> %vecins, <2 x half> addrspace(1)* %out.gep
362  ret void
363}
364
365; GCN-LABEL: {{^}}v_insertelement_v2f16_1:
366; VI: v_mov_b32_e32 [[K:v[0-9]+]], 0x45000000
367; GCN-DAG: {{flat|global}}_load_dword [[VEC:v[0-9]+]]
368
369; GFX9-DAG: s_movk_i32 [[K:s[0-9]+]], 0x4500
370; GFX9-DAG: v_and_b32_e32 [[ELT0:v[0-9]+]], 0xffff, [[VEC]]
371; GFX9: v_lshl_or_b32 [[RES:v[0-9]+]], [[K]], 16, [[ELT0]]
372
373; CI: v_and_b32_e32 [[AND:v[0-9]+]], 0xffff, [[VEC]]
374; CI: v_or_b32_e32 [[RES:v[0-9]+]], 0x45000000, [[AND]]
375
376; VI: v_or_b32_sdwa [[RES:v[0-9]+]], [[K]], [[VEC]] dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
377
378; GCN: {{flat|global}}_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RES]]
379define amdgpu_kernel void @v_insertelement_v2f16_1(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %in) #0 {
380  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
381  %tid.ext = sext i32 %tid to i64
382  %in.gep = getelementptr inbounds <2 x half>, <2 x half> addrspace(1)* %in, i64 %tid.ext
383  %out.gep = getelementptr inbounds <2 x half>, <2 x half> addrspace(1)* %out, i64 %tid.ext
384  %vec = load <2 x half>, <2 x half> addrspace(1)* %in.gep
385  %vecins = insertelement <2 x half> %vec, half 5.000000e+00, i32 1
386  store <2 x half> %vecins, <2 x half> addrspace(1)* %out.gep
387  ret void
388}
389
390; GCN-LABEL: {{^}}v_insertelement_v2f16_1_inlineimm:
391; VI: v_mov_b32_e32 [[K:v[0-9]+]], 0x230000
392; GCN: {{flat|global}}_load_dword [[VEC:v[0-9]+]]
393; CI: v_and_b32_e32 [[ELT0:v[0-9]+]], 0xffff, [[VEC]]
394; GFX9: v_and_b32_e32 [[ELT0:v[0-9]+]], 0xffff, [[VEC]]
395; CI: v_or_b32_e32 [[RES:v[0-9]+]], 0x230000, [[ELT0]]
396; VI: v_or_b32_sdwa [[RES:v[0-9]+]], [[K]], [[VEC]] dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
397; GFX9: v_lshl_or_b32 [[RES:v[0-9]+]], 35, 16, [[ELT0]]
398; GCN: {{flat|global}}_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RES]]
399define amdgpu_kernel void @v_insertelement_v2f16_1_inlineimm(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %in) #0 {
400  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
401  %tid.ext = sext i32 %tid to i64
402  %in.gep = getelementptr inbounds <2 x half>, <2 x half> addrspace(1)* %in, i64 %tid.ext
403  %out.gep = getelementptr inbounds <2 x half>, <2 x half> addrspace(1)* %out, i64 %tid.ext
404  %vec = load <2 x half>, <2 x half> addrspace(1)* %in.gep
405  %vecins = insertelement <2 x half> %vec, half 0xH0023, i32 1
406  store <2 x half> %vecins, <2 x half> addrspace(1)* %out.gep
407  ret void
408}
409
410; FIXME: Enable for others when argument load not split
411; GCN-LABEL: {{^}}s_insertelement_v2i16_dynamic:
412; GCN-DAG: v_mov_b32_e32 [[K:v[0-9]+]], 0x3e7
413; GCN: s_load_dword [[IDX:s[0-9]+]]
414; GCN: s_load_dword [[VEC:s[0-9]+]]
415; GCN-DAG: v_mov_b32_e32 [[VVEC:v[0-9]+]], [[VEC]]
416; GCN-DAG: s_lshl_b32 [[SCALED_IDX:s[0-9]+]], [[IDX]], 4
417; GCN-DAG: s_lshl_b32 [[MASK:s[0-9]+]], 0xffff, [[SCALED_IDX]]
418; GCN: v_bfi_b32 [[RESULT:v[0-9]+]], [[MASK]], [[K]], [[VVEC]]
419; GCN: {{flat|global}}_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]]
420define amdgpu_kernel void @s_insertelement_v2i16_dynamic(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(4)* %vec.ptr, i32 addrspace(4)* %idx.ptr) #0 {
421  %idx = load volatile i32, i32 addrspace(4)* %idx.ptr
422  %vec = load <2 x i16>, <2 x i16> addrspace(4)* %vec.ptr
423  %vecins = insertelement <2 x i16> %vec, i16 999, i32 %idx
424  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out
425  ret void
426}
427
428; GCN-LABEL: {{^}}v_insertelement_v2i16_dynamic_sgpr:
429; GCN-DAG: {{flat|global}}_load_dword [[VEC:v[0-9]+]]
430; GCN-DAG: s_load_dword [[IDX:s[0-9]+]]
431; GCN-DAG: v_mov_b32_e32 [[K:v[0-9]+]], 0x3e7
432; GCN-DAG: s_lshl_b32 [[SCALED_IDX:s[0-9]+]], [[IDX]], 4
433; GCN-DAG: s_lshl_b32 [[MASK:s[0-9]+]], 0xffff, [[SCALED_IDX]]
434; GCN: v_bfi_b32 [[RESULT:v[0-9]+]], [[MASK]], [[K]], [[VEC]]
435; GCN: {{flat|global}}_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]]
436define amdgpu_kernel void @v_insertelement_v2i16_dynamic_sgpr(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in, i32 %idx) #0 {
437  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
438  %tid.ext = sext i32 %tid to i64
439  %in.gep = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in, i64 %tid.ext
440  %out.gep = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %out, i64 %tid.ext
441  %vec = load <2 x i16>, <2 x i16> addrspace(1)* %in.gep
442  %vecins = insertelement <2 x i16> %vec, i16 999, i32 %idx
443  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out.gep
444  ret void
445}
446
447; GCN-LABEL: {{^}}v_insertelement_v2i16_dynamic_vgpr:
448; GFX89-DAG: s_mov_b32 [[MASKK:s[0-9]+]], 0xffff{{$}}
449; GCN-DAG: s_movk_i32 [[K:s[0-9]+]], 0x3e7
450
451; GCN: {{flat|global}}_load_dword [[IDX:v[0-9]+]]
452; GCN: {{flat|global}}_load_dword [[VEC:v[0-9]+]]
453
454; GFX89-DAG: v_lshlrev_b32_e32 [[SCALED_IDX:v[0-9]+]], 4, [[IDX]]
455; GFX89-DAG: v_lshlrev_b32_e64 [[MASK:v[0-9]+]], [[SCALED_IDX]], [[MASKK]]
456
457; CI-DAG: v_lshlrev_b32_e32 [[SCALED_IDX:v[0-9]+]], 4, [[IDX]]
458; CI-DAG: v_lshl_b32_e32 [[MASK:v[0-9]+]], 0xffff, [[SCALED_IDX]]
459
460; GCN: v_bfi_b32 [[RESULT:v[0-9]+]], [[MASK]], [[K]], [[VEC]]
461; GCN: {{flat|global}}_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]]
462define amdgpu_kernel void @v_insertelement_v2i16_dynamic_vgpr(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in, i32 addrspace(1)* %idx.ptr) #0 {
463  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
464  %tid.ext = sext i32 %tid to i64
465  %in.gep = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in, i64 %tid.ext
466  %idx.gep = getelementptr inbounds i32, i32 addrspace(1)* %idx.ptr, i64 %tid.ext
467  %out.gep = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %out, i64 %tid.ext
468  %idx = load i32, i32 addrspace(1)* %idx.gep
469  %vec = load <2 x i16>, <2 x i16> addrspace(1)* %in.gep
470  %vecins = insertelement <2 x i16> %vec, i16 999, i32 %idx
471  store <2 x i16> %vecins, <2 x i16> addrspace(1)* %out.gep
472  ret void
473}
474
475; GCN-LABEL: {{^}}v_insertelement_v2f16_dynamic_vgpr:
476; GFX89-DAG: s_mov_b32 [[MASKK:s[0-9]+]], 0xffff{{$}}
477; GCN-DAG: s_movk_i32 [[K:s[0-9]+]], 0x1234
478
479; GCN: {{flat|global}}_load_dword [[IDX:v[0-9]+]]
480; GCN: {{flat|global}}_load_dword [[VEC:v[0-9]+]]
481
482; GFX89-DAG: v_lshlrev_b32_e32 [[SCALED_IDX:v[0-9]+]], 4, [[IDX]]
483; GFX89-DAG: v_lshlrev_b32_e64 [[MASK:v[0-9]+]], [[SCALED_IDX]], [[MASKK]]
484
485; CI-DAG: v_lshlrev_b32_e32 [[SCALED_IDX:v[0-9]+]], 4, [[IDX]]
486; CI-DAG: v_lshl_b32_e32 [[MASK:v[0-9]+]], 0xffff, [[SCALED_IDX]]
487
488; GCN: v_bfi_b32 [[RESULT:v[0-9]+]], [[MASK]], [[K]], [[VEC]]
489; GCN: {{flat|global}}_store_dword v{{\[[0-9]+:[0-9]+\]}}, [[RESULT]]
490define amdgpu_kernel void @v_insertelement_v2f16_dynamic_vgpr(<2 x half> addrspace(1)* %out, <2 x half> addrspace(1)* %in, i32 addrspace(1)* %idx.ptr) #0 {
491  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
492  %tid.ext = sext i32 %tid to i64
493  %in.gep = getelementptr inbounds <2 x half>, <2 x half> addrspace(1)* %in, i64 %tid.ext
494  %idx.gep = getelementptr inbounds i32, i32 addrspace(1)* %idx.ptr, i64 %tid.ext
495  %out.gep = getelementptr inbounds <2 x half>, <2 x half> addrspace(1)* %out, i64 %tid.ext
496  %idx = load i32, i32 addrspace(1)* %idx.gep
497  %vec = load <2 x half>, <2 x half> addrspace(1)* %in.gep
498  %vecins = insertelement <2 x half> %vec, half 0xH1234, i32 %idx
499  store <2 x half> %vecins, <2 x half> addrspace(1)* %out.gep
500  ret void
501}
502
503; GCN-LABEL: {{^}}v_insertelement_v4f16_0:
504; GCN-DAG: s_load_dword [[VAL:s[0-9]+]], s[4:5],
505; GCN-DAG: {{flat|global}}_load_dwordx2 v{{\[}}[[LO:[0-9]+]]:[[HI:[0-9]+]]{{\]}}
506
507; GFX9-DAG: v_mov_b32_e32 [[BFI_MASK:v[0-9]+]], 0xffff{{$}}
508; GFX9: v_bfi_b32 v[[INS_LO:[0-9]+]], [[BFI_MASK]], [[VAL]], v[[LO]]
509
510; CIVI: s_and_b32 [[VAL_MASKED:s[0-9]+]], [[VAL]], 0xffff{{$}}
511; CIVI: v_and_b32_e32 [[AND:v[0-9]+]], 0xffff0000, v[[LO]]
512; CIVI: v_or_b32_e32 v[[INS_LO:[0-9]+]], [[VAL_MASKED]], [[AND]]
513
514; GCN: {{flat|global}}_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[INS_LO]]:[[HI]]{{\]}}
515define amdgpu_kernel void @v_insertelement_v4f16_0(<4 x half> addrspace(1)* %out, <4 x half> addrspace(1)* %in, [8 x i32], i32 %val) #0 {
516  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
517  %tid.ext = sext i32 %tid to i64
518  %in.gep = getelementptr inbounds <4 x half>, <4 x half> addrspace(1)* %in, i64 %tid.ext
519  %out.gep = getelementptr inbounds <4 x half>, <4 x half> addrspace(1)* %out, i64 %tid.ext
520  %vec = load <4 x half>, <4 x half> addrspace(1)* %in.gep
521  %val.trunc = trunc i32 %val to i16
522  %val.cvt = bitcast i16 %val.trunc to half
523  %vecins = insertelement <4 x half> %vec, half %val.cvt, i32 0
524  store <4 x half> %vecins, <4 x half> addrspace(1)* %out.gep
525  ret void
526}
527
528; GCN-LABEL: {{^}}v_insertelement_v4f16_1:
529; GCN-DAG: s_load_dword [[VAL:s[0-9]+]]
530; GCN-DAG: {{flat|global}}_load_dwordx2 v{{\[}}[[LO:[0-9]+]]:[[HI:[0-9]+]]{{\]}}
531
532; GFX9: v_and_b32_e32 [[AND:v[0-9]+]], 0xffff, v[[LO]]
533; GFX9: v_lshl_or_b32 v[[INS_HALF:[0-9]+]], [[VAL]], 16, [[AND]]
534
535; VI: s_lshl_b32 [[VAL_HI:s[0-9]+]], [[VAL]], 16
536; VI-DAG: v_mov_b32_e32 [[COPY_VAL:v[0-9]+]], [[VAL_HI]]
537; VI: v_or_b32_sdwa v[[INS_HALF:[0-9]+]], [[COPY_VAL]], v[[LO]] dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
538
539; CI: s_lshl_b32 [[VAL_HI:s[0-9]+]], [[VAL]], 16
540; CI: v_and_b32_e32 [[AND:v[0-9]+]], 0xffff, v[[LO]]
541; CI: v_or_b32_e32 v[[INS_HALF:[0-9]+]], [[VAL_HI]], [[AND]]
542
543; GCN: {{flat|global}}_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[INS_HALF]]:[[HI]]{{\]}}
544define amdgpu_kernel void @v_insertelement_v4f16_1(<4 x half> addrspace(1)* %out, <4 x half> addrspace(1)* %in, i32 %val) #0 {
545  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
546  %tid.ext = sext i32 %tid to i64
547  %in.gep = getelementptr inbounds <4 x half>, <4 x half> addrspace(1)* %in, i64 %tid.ext
548  %out.gep = getelementptr inbounds <4 x half>, <4 x half> addrspace(1)* %out, i64 %tid.ext
549  %vec = load <4 x half>, <4 x half> addrspace(1)* %in.gep
550  %val.trunc = trunc i32 %val to i16
551  %val.cvt = bitcast i16 %val.trunc to half
552  %vecins = insertelement <4 x half> %vec, half %val.cvt, i32 1
553  store <4 x half> %vecins, <4 x half> addrspace(1)* %out.gep
554  ret void
555}
556
557; GCN-LABEL: {{^}}v_insertelement_v4f16_2:
558; GCN-DAG: s_load_dword [[VAL:s[0-9]+]], s[4:5],
559; GCN-DAG: {{flat|global}}_load_dwordx2 v{{\[}}[[LO:[0-9]+]]:[[HI:[0-9]+]]{{\]}}
560
561; GFX9-DAG: v_mov_b32_e32 [[BFI_MASK:v[0-9]+]], 0xffff{{$}}
562; GFX9: v_bfi_b32 v[[INS_HI:[0-9]+]], [[BFI_MASK]], [[VAL]], v[[HI]]
563
564; CIVI: s_and_b32 [[VAL_MASKED:s[0-9]+]], [[VAL]], 0xffff{{$}}
565; CIVI: v_and_b32_e32 [[AND:v[0-9]+]], 0xffff0000, v[[HI]]
566; CIVI: v_or_b32_e32 v[[INS_HI:[0-9]+]], [[VAL_MASKED]], [[AND]]
567
568; GCN: {{flat|global}}_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[LO]]:[[INS_HI]]{{\]}}
569define amdgpu_kernel void @v_insertelement_v4f16_2(<4 x half> addrspace(1)* %out, <4 x half> addrspace(1)* %in, [8 x i32], i32 %val) #0 {
570  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
571  %tid.ext = sext i32 %tid to i64
572  %in.gep = getelementptr inbounds <4 x half>, <4 x half> addrspace(1)* %in, i64 %tid.ext
573  %out.gep = getelementptr inbounds <4 x half>, <4 x half> addrspace(1)* %out, i64 %tid.ext
574  %vec = load <4 x half>, <4 x half> addrspace(1)* %in.gep
575  %val.trunc = trunc i32 %val to i16
576  %val.cvt = bitcast i16 %val.trunc to half
577  %vecins = insertelement <4 x half> %vec, half %val.cvt, i32 2
578  store <4 x half> %vecins, <4 x half> addrspace(1)* %out.gep
579  ret void
580}
581
582; GCN-LABEL: {{^}}v_insertelement_v4f16_3:
583; GCN-DAG: s_load_dword [[VAL:s[0-9]+]]
584; GCN-DAG: {{flat|global}}_load_dwordx2 v{{\[}}[[LO:[0-9]+]]:[[HI:[0-9]+]]{{\]}}
585
586; GFX9: v_and_b32_e32 [[AND:v[0-9]+]], 0xffff, v[[HI]]
587; GFX9: v_lshl_or_b32 v[[INS_HI:[0-9]+]], [[VAL]], 16, [[AND]]
588
589; VI: s_lshl_b32 [[VAL_HI:s[0-9]+]], [[VAL]], 16
590; VI-DAG: v_mov_b32_e32 [[COPY_VAL:v[0-9]+]], [[VAL_HI]]
591; VI: v_or_b32_sdwa v[[INS_HI:[0-9]+]], [[COPY_VAL]], v[[HI]] dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
592
593; CI: s_lshl_b32 [[VAL_HI:s[0-9]+]], [[VAL]], 16
594; CI: v_and_b32_e32 [[AND:v[0-9]+]], 0xffff, v[[HI]]
595; CI: v_or_b32_e32 v[[INS_HI:[0-9]+]], [[VAL_HI]], [[AND]]
596
597; GCN: {{flat|global}}_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[LO]]:[[INS_HI]]{{\]}}
598define amdgpu_kernel void @v_insertelement_v4f16_3(<4 x half> addrspace(1)* %out, <4 x half> addrspace(1)* %in, i32 %val) #0 {
599  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
600  %tid.ext = sext i32 %tid to i64
601  %in.gep = getelementptr inbounds <4 x half>, <4 x half> addrspace(1)* %in, i64 %tid.ext
602  %out.gep = getelementptr inbounds <4 x half>, <4 x half> addrspace(1)* %out, i64 %tid.ext
603  %vec = load <4 x half>, <4 x half> addrspace(1)* %in.gep
604  %val.trunc = trunc i32 %val to i16
605  %val.cvt = bitcast i16 %val.trunc to half
606  %vecins = insertelement <4 x half> %vec, half %val.cvt, i32 3
607  store <4 x half> %vecins, <4 x half> addrspace(1)* %out.gep
608  ret void
609}
610
611; GCN-LABEL: {{^}}v_insertelement_v4i16_2:
612; GCN-DAG: s_load_dword [[VAL:s[0-9]+]]
613; GCN-DAG: {{flat|global}}_load_dwordx2 v{{\[}}[[LO:[0-9]+]]:[[HI:[0-9]+]]{{\]}}
614
615; GFX9-DAG: v_mov_b32_e32 [[BFI_MASK:v[0-9]+]], 0xffff{{$}}
616; GFX9: v_bfi_b32 v[[INS_HI:[0-9]+]], [[BFI_MASK]], [[VAL]], v[[HI]]
617
618; CIVI: s_and_b32 [[VAL_MASKED:s[0-9]+]], [[VAL]], 0xffff{{$}}
619; CIVI: v_and_b32_e32 [[AND:v[0-9]+]], 0xffff0000, v[[HI]]
620; CIVI: v_or_b32_e32 v[[INS_HI:[0-9]+]], [[VAL_MASKED]], [[AND]]
621
622; GCN: {{flat|global}}_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[LO]]:[[INS_HI]]{{\]}}
623define amdgpu_kernel void @v_insertelement_v4i16_2(<4 x i16> addrspace(1)* %out, <4 x i16> addrspace(1)* %in, i32 %val) #0 {
624  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
625  %tid.ext = sext i32 %tid to i64
626  %in.gep = getelementptr inbounds <4 x i16>, <4 x i16> addrspace(1)* %in, i64 %tid.ext
627  %out.gep = getelementptr inbounds <4 x i16>, <4 x i16> addrspace(1)* %out, i64 %tid.ext
628  %vec = load <4 x i16>, <4 x i16> addrspace(1)* %in.gep
629  %val.trunc = trunc i32 %val to i16
630  %val.cvt = bitcast i16 %val.trunc to i16
631  %vecins = insertelement <4 x i16> %vec, i16 %val.cvt, i32 2
632  store <4 x i16> %vecins, <4 x i16> addrspace(1)* %out.gep
633  ret void
634}
635
636; FIXME: Better code on CI?
637; GCN-LABEL: {{^}}v_insertelement_v4i16_dynamic_vgpr:
638; GCN-DAG: {{flat|global}}_load_dword [[IDX:v[0-9]+]],
639; GCN-DAG: s_load_dword [[VAL:s[0-9]+]]
640; GCN-DAG: {{flat|global}}_load_dwordx2 v{{\[}}[[LO:[0-9]+]]:[[HI:[0-9]+]]{{\]}}
641
642; GCN-DAG: v_lshlrev_b32_e32 [[SCALED_IDX:v[0-9]+]], 4, [[IDX]]
643; GCN-DAG: s_mov_b32 s[[MASK_HI:[0-9]+]], 0
644; GCN-DAG: s_mov_b32 s[[MASK_LO:[0-9]+]], 0xffff{{$}}
645
646; GFX89: v_lshlrev_b64 v{{\[}}[[SHIFT_LO:[0-9]+]]:[[SHIFT_HI:[0-9]+]]{{\]}}, [[SCALED_IDX]], s{{\[}}[[MASK_LO]]:[[MASK_HI]]{{\]}}
647; GFX89-DAG: v_not_b32_e32 v[[NOT_SHIFT_LO:[0-9+]]], v[[SHIFT_LO]]
648; GFX89-DAG: v_not_b32_e32 v[[NOT_SHIFT_HI:[0-9+]]], v[[SHIFT_HI]]
649; GFX89-DAG: v_and_b32_e32 v[[MASK:[0-9]+]], [[VAL]], v[[SHIFT_LO]]
650
651; GFX89-DAG: v_and_b32_e32 v[[AND0:[0-9]+]], v[[NOT_SHIFT_LO]], v[[LO]]
652; GFX89-DAG: v_and_b32_e32 v[[AND1:[0-9]+]], v[[NOT_SHIFT_HI]], v[[HI]]
653; GFX89: v_or_b32_sdwa v[[OR_SDWA:[0-9]+]], v[[MASK]], v[[AND0]] dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
654
655
656; CI: v_lshl_b64 v{{\[}}[[SHIFT_LO:[0-9]+]]:[[SHIFT_HI:[0-9]+]]{{\]}}, s{{\[}}[[MASK_LO]]:[[MASK_HI]]{{\]}}, [[SCALED_IDX]]
657; CI-DAG: v_bfi_b32 v[[OR_SDWA:[0-9]+]], v[[SHIFT_LO]],
658; CI-DAG: v_bfi_b32 v[[AND1:[0-9]+]], v[[SHIFT_HI]], 0,
659
660; GCN: {{flat|global}}_store_dwordx2 v{{\[[0-9]+:[0-9]+\]}}, v{{\[}}[[OR_SDWA]]:[[AND1]]{{\]}}
661define amdgpu_kernel void @v_insertelement_v4i16_dynamic_vgpr(<4 x i16> addrspace(1)* %out, <4 x i16> addrspace(1)* %in, i32 %val) #0 {
662  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
663  %tid.ext = sext i32 %tid to i64
664  %in.gep = getelementptr inbounds <4 x i16>, <4 x i16> addrspace(1)* %in, i64 %tid.ext
665  %out.gep = getelementptr inbounds <4 x i16>, <4 x i16> addrspace(1)* %out, i64 %tid.ext
666  %idx.val = load volatile i32, i32 addrspace(1)* undef
667  %vec = load <4 x i16>, <4 x i16> addrspace(1)* %in.gep
668  %val.trunc = trunc i32 %val to i16
669  %val.cvt = bitcast i16 %val.trunc to i16
670  %vecins = insertelement <4 x i16> %vec, i16 %val.cvt, i32 %idx.val
671  store <4 x i16> %vecins, <4 x i16> addrspace(1)* %out.gep
672  ret void
673}
674
675; GCN-LABEL: {{^}}v_insertelement_v4f16_dynamic_sgpr:
676define amdgpu_kernel void @v_insertelement_v4f16_dynamic_sgpr(<4 x half> addrspace(1)* %out, <4 x half> addrspace(1)* %in, i32 %val, i32 %idxval) #0 {
677  %tid = call i32 @llvm.amdgcn.workitem.id.x() #1
678  %tid.ext = sext i32 %tid to i64
679  %in.gep = getelementptr inbounds <4 x half>, <4 x half> addrspace(1)* %in, i64 %tid.ext
680  %out.gep = getelementptr inbounds <4 x half>, <4 x half> addrspace(1)* %out, i64 %tid.ext
681  %vec = load <4 x half>, <4 x half> addrspace(1)* %in.gep
682  %val.trunc = trunc i32 %val to i16
683  %val.cvt = bitcast i16 %val.trunc to half
684  %vecins = insertelement <4 x half> %vec, half %val.cvt, i32 %idxval
685  store <4 x half> %vecins, <4 x half> addrspace(1)* %out.gep
686  ret void
687}
688
689declare i32 @llvm.amdgcn.workitem.id.x() #1
690
691attributes #0 = { nounwind }
692attributes #1 = { nounwind readnone }
693