1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -march=amdgcn -mcpu=gfx900 -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck %s -enable-var-scope -check-prefixes=GCN,GFX9
3; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck %s -enable-var-scope -check-prefixes=GCN,VI
4; RUN: llc -march=amdgcn -mcpu=gfx1010 -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck %s -enable-var-scope -check-prefixes=GFX10
5
6; FIXME: Need to handle non-uniform case for function below (load without gep).
7define amdgpu_kernel void @v_test_sub_v2i16(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in0, <2 x i16> addrspace(1)* %in1) #1 {
8; GFX9-LABEL: v_test_sub_v2i16:
9; GFX9:       ; %bb.0:
10; GFX9-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
11; GFX9-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x34
12; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
13; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
14; GFX9-NEXT:    global_load_dword v1, v0, s[6:7] glc
15; GFX9-NEXT:    s_waitcnt vmcnt(0)
16; GFX9-NEXT:    global_load_dword v2, v0, s[2:3] glc
17; GFX9-NEXT:    s_waitcnt vmcnt(0)
18; GFX9-NEXT:    s_mov_b32 s7, 0xf000
19; GFX9-NEXT:    s_mov_b32 s6, -1
20; GFX9-NEXT:    v_pk_sub_i16 v0, v1, v2
21; GFX9-NEXT:    buffer_store_dword v0, off, s[4:7], 0
22; GFX9-NEXT:    s_endpgm
23;
24; VI-LABEL: v_test_sub_v2i16:
25; VI:       ; %bb.0:
26; VI-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
27; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x34
28; VI-NEXT:    v_lshlrev_b32_e32 v2, 2, v0
29; VI-NEXT:    s_waitcnt lgkmcnt(0)
30; VI-NEXT:    v_mov_b32_e32 v1, s7
31; VI-NEXT:    v_add_u32_e32 v0, vcc, s6, v2
32; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
33; VI-NEXT:    v_mov_b32_e32 v3, s1
34; VI-NEXT:    v_add_u32_e32 v2, vcc, s0, v2
35; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v3, vcc
36; VI-NEXT:    flat_load_dword v0, v[0:1] glc
37; VI-NEXT:    s_waitcnt vmcnt(0)
38; VI-NEXT:    flat_load_dword v1, v[2:3] glc
39; VI-NEXT:    s_waitcnt vmcnt(0)
40; VI-NEXT:    s_mov_b32 s7, 0xf000
41; VI-NEXT:    s_mov_b32 s6, -1
42; VI-NEXT:    v_sub_u16_e32 v2, v0, v1
43; VI-NEXT:    v_sub_u16_sdwa v0, v0, v1 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:WORD_1
44; VI-NEXT:    v_or_b32_e32 v0, v2, v0
45; VI-NEXT:    buffer_store_dword v0, off, s[4:7], 0
46; VI-NEXT:    s_endpgm
47;
48; GFX10-LABEL: v_test_sub_v2i16:
49; GFX10:       ; %bb.0:
50; GFX10-NEXT:    s_clause 0x1
51; GFX10-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
52; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x34
53; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
54; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
55; GFX10-NEXT:    global_load_dword v1, v0, s[6:7] glc dlc
56; GFX10-NEXT:    s_waitcnt vmcnt(0)
57; GFX10-NEXT:    global_load_dword v2, v0, s[2:3] glc dlc
58; GFX10-NEXT:    s_waitcnt vmcnt(0)
59; GFX10-NEXT:    s_waitcnt_depctr 0xffe3
60; GFX10-NEXT:    s_mov_b32 s7, 0x31016000
61; GFX10-NEXT:    s_mov_b32 s6, -1
62; GFX10-NEXT:    v_pk_sub_i16 v0, v1, v2
63; GFX10-NEXT:    buffer_store_dword v0, off, s[4:7], 0
64; GFX10-NEXT:    s_endpgm
65  %tid = call i32 @llvm.amdgcn.workitem.id.x()
66  %gep.out = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %out, i32 %tid
67  %gep.in0 = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in0, i32 %tid
68  %gep.in1 = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in1, i32 %tid
69  %a = load volatile <2 x i16>, <2 x i16> addrspace(1)* %gep.in0
70  %b = load volatile <2 x i16>, <2 x i16> addrspace(1)* %gep.in1
71  %add = sub <2 x i16> %a, %b
72  store <2 x i16> %add, <2 x i16> addrspace(1)* %out
73  ret void
74}
75
76define amdgpu_kernel void @s_test_sub_v2i16(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(4)* %in0, <2 x i16> addrspace(4)* %in1) #1 {
77; GFX9-LABEL: s_test_sub_v2i16:
78; GFX9:       ; %bb.0:
79; GFX9-NEXT:    s_load_dwordx2 s[8:9], s[0:1], 0x34
80; GFX9-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
81; GFX9-NEXT:    s_mov_b32 s3, 0xf000
82; GFX9-NEXT:    s_mov_b32 s2, -1
83; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
84; GFX9-NEXT:    s_load_dword s10, s[8:9], 0x0
85; GFX9-NEXT:    s_load_dword s11, s[6:7], 0x0
86; GFX9-NEXT:    s_mov_b32 s0, s4
87; GFX9-NEXT:    s_mov_b32 s1, s5
88; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
89; GFX9-NEXT:    v_mov_b32_e32 v0, s10
90; GFX9-NEXT:    v_pk_sub_i16 v0, s11, v0
91; GFX9-NEXT:    buffer_store_dword v0, off, s[0:3], 0
92; GFX9-NEXT:    s_endpgm
93;
94; VI-LABEL: s_test_sub_v2i16:
95; VI:       ; %bb.0:
96; VI-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
97; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x34
98; VI-NEXT:    s_mov_b32 s3, 0xf000
99; VI-NEXT:    s_mov_b32 s2, -1
100; VI-NEXT:    s_waitcnt lgkmcnt(0)
101; VI-NEXT:    s_load_dword s6, s[6:7], 0x0
102; VI-NEXT:    s_load_dword s7, s[0:1], 0x0
103; VI-NEXT:    s_mov_b32 s0, s4
104; VI-NEXT:    s_mov_b32 s1, s5
105; VI-NEXT:    s_waitcnt lgkmcnt(0)
106; VI-NEXT:    s_lshr_b32 s4, s6, 16
107; VI-NEXT:    s_lshr_b32 s5, s7, 16
108; VI-NEXT:    s_sub_i32 s6, s6, s7
109; VI-NEXT:    s_sub_i32 s4, s4, s5
110; VI-NEXT:    s_and_b32 s5, s6, 0xffff
111; VI-NEXT:    s_lshl_b32 s4, s4, 16
112; VI-NEXT:    s_or_b32 s4, s5, s4
113; VI-NEXT:    v_mov_b32_e32 v0, s4
114; VI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
115; VI-NEXT:    s_endpgm
116;
117; GFX10-LABEL: s_test_sub_v2i16:
118; GFX10:       ; %bb.0:
119; GFX10-NEXT:    s_clause 0x1
120; GFX10-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
121; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x34
122; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
123; GFX10-NEXT:    s_load_dword s0, s[6:7], 0x0
124; GFX10-NEXT:    s_load_dword s1, s[2:3], 0x0
125; GFX10-NEXT:    s_mov_b32 s7, 0x31016000
126; GFX10-NEXT:    s_mov_b32 s6, -1
127; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
128; GFX10-NEXT:    v_pk_sub_i16 v0, s0, s1
129; GFX10-NEXT:    buffer_store_dword v0, off, s[4:7], 0
130; GFX10-NEXT:    s_endpgm
131  %a = load <2 x i16>, <2 x i16> addrspace(4)* %in0
132  %b = load <2 x i16>, <2 x i16> addrspace(4)* %in1
133  %add = sub <2 x i16> %a, %b
134  store <2 x i16> %add, <2 x i16> addrspace(1)* %out
135  ret void
136}
137
138define amdgpu_kernel void @s_test_sub_self_v2i16(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(4)* %in0) #1 {
139; GCN-LABEL: s_test_sub_self_v2i16:
140; GCN:       ; %bb.0:
141; GCN-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
142; GCN-NEXT:    s_mov_b32 s3, 0xf000
143; GCN-NEXT:    s_mov_b32 s2, -1
144; GCN-NEXT:    v_mov_b32_e32 v0, 0
145; GCN-NEXT:    s_waitcnt lgkmcnt(0)
146; GCN-NEXT:    buffer_store_dword v0, off, s[0:3], 0
147; GCN-NEXT:    s_endpgm
148;
149; GFX10-LABEL: s_test_sub_self_v2i16:
150; GFX10:       ; %bb.0:
151; GFX10-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
152; GFX10-NEXT:    v_mov_b32_e32 v0, 0
153; GFX10-NEXT:    s_mov_b32 s3, 0x31016000
154; GFX10-NEXT:    s_mov_b32 s2, -1
155; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
156; GFX10-NEXT:    buffer_store_dword v0, off, s[0:3], 0
157; GFX10-NEXT:    s_endpgm
158  %a = load <2 x i16>, <2 x i16> addrspace(4)* %in0
159  %add = sub <2 x i16> %a, %a
160  store <2 x i16> %add, <2 x i16> addrspace(1)* %out
161  ret void
162}
163
164; FIXME: VI should not scalarize arg access.
165define amdgpu_kernel void @s_test_sub_v2i16_kernarg(<2 x i16> addrspace(1)* %out, <2 x i16> %a, <2 x i16> %b) #1 {
166; GFX9-LABEL: s_test_sub_v2i16_kernarg:
167; GFX9:       ; %bb.0:
168; GFX9-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
169; GFX9-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
170; GFX9-NEXT:    s_mov_b32 s7, 0xf000
171; GFX9-NEXT:    s_mov_b32 s6, -1
172; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
173; GFX9-NEXT:    v_mov_b32_e32 v0, s3
174; GFX9-NEXT:    v_pk_sub_i16 v0, s2, v0
175; GFX9-NEXT:    buffer_store_dword v0, off, s[4:7], 0
176; GFX9-NEXT:    s_endpgm
177;
178; VI-LABEL: s_test_sub_v2i16_kernarg:
179; VI:       ; %bb.0:
180; VI-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x2c
181; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x24
182; VI-NEXT:    s_mov_b32 s3, 0xf000
183; VI-NEXT:    s_mov_b32 s2, -1
184; VI-NEXT:    s_waitcnt lgkmcnt(0)
185; VI-NEXT:    s_lshr_b32 s6, s4, 16
186; VI-NEXT:    s_lshr_b32 s7, s5, 16
187; VI-NEXT:    s_sub_i32 s6, s6, s7
188; VI-NEXT:    s_sub_i32 s4, s4, s5
189; VI-NEXT:    s_lshl_b32 s5, s6, 16
190; VI-NEXT:    s_and_b32 s4, s4, 0xffff
191; VI-NEXT:    s_or_b32 s4, s4, s5
192; VI-NEXT:    v_mov_b32_e32 v0, s4
193; VI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
194; VI-NEXT:    s_endpgm
195;
196; GFX10-LABEL: s_test_sub_v2i16_kernarg:
197; GFX10:       ; %bb.0:
198; GFX10-NEXT:    s_clause 0x1
199; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x2c
200; GFX10-NEXT:    s_load_dwordx2 s[4:5], s[0:1], 0x24
201; GFX10-NEXT:    s_mov_b32 s7, 0x31016000
202; GFX10-NEXT:    s_mov_b32 s6, -1
203; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
204; GFX10-NEXT:    v_pk_sub_i16 v0, s2, s3
205; GFX10-NEXT:    buffer_store_dword v0, off, s[4:7], 0
206; GFX10-NEXT:    s_endpgm
207  %add = sub <2 x i16> %a, %b
208  store <2 x i16> %add, <2 x i16> addrspace(1)* %out
209  ret void
210}
211
212define amdgpu_kernel void @v_test_sub_v2i16_constant(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in0) #1 {
213; GFX9-LABEL: v_test_sub_v2i16_constant:
214; GFX9:       ; %bb.0:
215; GFX9-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x24
216; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
217; GFX9-NEXT:    s_mov_b32 s4, 0x1c8007b
218; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
219; GFX9-NEXT:    global_load_dword v0, v0, s[2:3] glc
220; GFX9-NEXT:    s_waitcnt vmcnt(0)
221; GFX9-NEXT:    s_mov_b32 s3, 0xf000
222; GFX9-NEXT:    s_mov_b32 s2, -1
223; GFX9-NEXT:    v_pk_sub_i16 v0, v0, s4
224; GFX9-NEXT:    buffer_store_dword v0, off, s[0:3], 0
225; GFX9-NEXT:    s_endpgm
226;
227; VI-LABEL: v_test_sub_v2i16_constant:
228; VI:       ; %bb.0:
229; VI-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x24
230; VI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
231; VI-NEXT:    s_waitcnt lgkmcnt(0)
232; VI-NEXT:    v_mov_b32_e32 v1, s3
233; VI-NEXT:    v_add_u32_e32 v0, vcc, s2, v0
234; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
235; VI-NEXT:    flat_load_dword v0, v[0:1] glc
236; VI-NEXT:    s_waitcnt vmcnt(0)
237; VI-NEXT:    v_mov_b32_e32 v1, 0xfffffe38
238; VI-NEXT:    s_mov_b32 s3, 0xf000
239; VI-NEXT:    s_mov_b32 s2, -1
240; VI-NEXT:    v_add_u16_e32 v2, 0xff85, v0
241; VI-NEXT:    v_add_u16_sdwa v0, v0, v1 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
242; VI-NEXT:    v_or_b32_e32 v0, v2, v0
243; VI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
244; VI-NEXT:    s_endpgm
245;
246; GFX10-LABEL: v_test_sub_v2i16_constant:
247; GFX10:       ; %bb.0:
248; GFX10-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x24
249; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
250; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
251; GFX10-NEXT:    global_load_dword v0, v0, s[2:3] glc dlc
252; GFX10-NEXT:    s_waitcnt vmcnt(0)
253; GFX10-NEXT:    s_waitcnt_depctr 0xffe3
254; GFX10-NEXT:    s_mov_b32 s3, 0x31016000
255; GFX10-NEXT:    s_mov_b32 s2, -1
256; GFX10-NEXT:    v_pk_sub_i16 v0, v0, 0x1c8007b
257; GFX10-NEXT:    buffer_store_dword v0, off, s[0:3], 0
258; GFX10-NEXT:    s_endpgm
259  %tid = call i32 @llvm.amdgcn.workitem.id.x()
260  %gep.out = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %out, i32 %tid
261  %gep.in0 = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in0, i32 %tid
262  %a = load volatile <2 x i16>, <2 x i16> addrspace(1)* %gep.in0
263  %add = sub <2 x i16> %a, <i16 123, i16 456>
264  store <2 x i16> %add, <2 x i16> addrspace(1)* %out
265  ret void
266}
267
268; FIXME: Need to handle non-uniform case for function below (load without gep).
269define amdgpu_kernel void @v_test_sub_v2i16_neg_constant(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in0) #1 {
270; GFX9-LABEL: v_test_sub_v2i16_neg_constant:
271; GFX9:       ; %bb.0:
272; GFX9-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x24
273; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
274; GFX9-NEXT:    s_mov_b32 s4, 0xfc21fcb3
275; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
276; GFX9-NEXT:    global_load_dword v0, v0, s[2:3] glc
277; GFX9-NEXT:    s_waitcnt vmcnt(0)
278; GFX9-NEXT:    s_mov_b32 s3, 0xf000
279; GFX9-NEXT:    s_mov_b32 s2, -1
280; GFX9-NEXT:    v_pk_sub_i16 v0, v0, s4
281; GFX9-NEXT:    buffer_store_dword v0, off, s[0:3], 0
282; GFX9-NEXT:    s_endpgm
283;
284; VI-LABEL: v_test_sub_v2i16_neg_constant:
285; VI:       ; %bb.0:
286; VI-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x24
287; VI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
288; VI-NEXT:    s_waitcnt lgkmcnt(0)
289; VI-NEXT:    v_mov_b32_e32 v1, s3
290; VI-NEXT:    v_add_u32_e32 v0, vcc, s2, v0
291; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
292; VI-NEXT:    flat_load_dword v0, v[0:1] glc
293; VI-NEXT:    s_waitcnt vmcnt(0)
294; VI-NEXT:    v_mov_b32_e32 v1, 0x3df
295; VI-NEXT:    s_mov_b32 s3, 0xf000
296; VI-NEXT:    s_mov_b32 s2, -1
297; VI-NEXT:    v_add_u16_e32 v2, 0x34d, v0
298; VI-NEXT:    v_add_u16_sdwa v0, v0, v1 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
299; VI-NEXT:    v_or_b32_e32 v0, v2, v0
300; VI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
301; VI-NEXT:    s_endpgm
302;
303; GFX10-LABEL: v_test_sub_v2i16_neg_constant:
304; GFX10:       ; %bb.0:
305; GFX10-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x24
306; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
307; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
308; GFX10-NEXT:    global_load_dword v0, v0, s[2:3] glc dlc
309; GFX10-NEXT:    s_waitcnt vmcnt(0)
310; GFX10-NEXT:    s_waitcnt_depctr 0xffe3
311; GFX10-NEXT:    s_mov_b32 s3, 0x31016000
312; GFX10-NEXT:    s_mov_b32 s2, -1
313; GFX10-NEXT:    v_pk_sub_i16 v0, v0, 0xfc21fcb3
314; GFX10-NEXT:    buffer_store_dword v0, off, s[0:3], 0
315; GFX10-NEXT:    s_endpgm
316  %tid = call i32 @llvm.amdgcn.workitem.id.x()
317  %gep.out = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %out, i32 %tid
318  %gep.in0 = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in0, i32 %tid
319  %a = load volatile <2 x i16>, <2 x i16> addrspace(1)* %gep.in0
320  %add = sub <2 x i16> %a, <i16 -845, i16 -991>
321  store <2 x i16> %add, <2 x i16> addrspace(1)* %out
322  ret void
323}
324
325define amdgpu_kernel void @v_test_sub_v2i16_inline_neg1(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in0) #1 {
326; GFX9-LABEL: v_test_sub_v2i16_inline_neg1:
327; GFX9:       ; %bb.0:
328; GFX9-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x24
329; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
330; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
331; GFX9-NEXT:    global_load_dword v0, v0, s[2:3] glc
332; GFX9-NEXT:    s_waitcnt vmcnt(0)
333; GFX9-NEXT:    s_mov_b32 s3, 0xf000
334; GFX9-NEXT:    s_mov_b32 s2, -1
335; GFX9-NEXT:    v_pk_sub_i16 v0, v0, -1 op_sel_hi:[1,0]
336; GFX9-NEXT:    buffer_store_dword v0, off, s[0:3], 0
337; GFX9-NEXT:    s_endpgm
338;
339; VI-LABEL: v_test_sub_v2i16_inline_neg1:
340; VI:       ; %bb.0:
341; VI-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x24
342; VI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
343; VI-NEXT:    s_waitcnt lgkmcnt(0)
344; VI-NEXT:    v_mov_b32_e32 v1, s3
345; VI-NEXT:    v_add_u32_e32 v0, vcc, s2, v0
346; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
347; VI-NEXT:    flat_load_dword v0, v[0:1] glc
348; VI-NEXT:    s_waitcnt vmcnt(0)
349; VI-NEXT:    v_mov_b32_e32 v1, 1
350; VI-NEXT:    s_mov_b32 s3, 0xf000
351; VI-NEXT:    s_mov_b32 s2, -1
352; VI-NEXT:    v_add_u16_e32 v2, 1, v0
353; VI-NEXT:    v_add_u16_sdwa v0, v0, v1 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
354; VI-NEXT:    v_or_b32_e32 v0, v2, v0
355; VI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
356; VI-NEXT:    s_endpgm
357;
358; GFX10-LABEL: v_test_sub_v2i16_inline_neg1:
359; GFX10:       ; %bb.0:
360; GFX10-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x24
361; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
362; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
363; GFX10-NEXT:    global_load_dword v0, v0, s[2:3] glc dlc
364; GFX10-NEXT:    s_waitcnt vmcnt(0)
365; GFX10-NEXT:    s_waitcnt_depctr 0xffe3
366; GFX10-NEXT:    s_mov_b32 s3, 0x31016000
367; GFX10-NEXT:    s_mov_b32 s2, -1
368; GFX10-NEXT:    v_pk_sub_i16 v0, v0, -1 op_sel_hi:[1,0]
369; GFX10-NEXT:    buffer_store_dword v0, off, s[0:3], 0
370; GFX10-NEXT:    s_endpgm
371  %tid = call i32 @llvm.amdgcn.workitem.id.x()
372  %gep.out = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %out, i32 %tid
373  %gep.in0 = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in0, i32 %tid
374  %a = load volatile <2 x i16>, <2 x i16> addrspace(1)* %gep.in0
375  %add = sub <2 x i16> %a, <i16 -1, i16 -1>
376  store <2 x i16> %add, <2 x i16> addrspace(1)* %out
377  ret void
378}
379
380define amdgpu_kernel void @v_test_sub_v2i16_inline_lo_zero_hi(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in0) #1 {
381; GFX9-LABEL: v_test_sub_v2i16_inline_lo_zero_hi:
382; GFX9:       ; %bb.0:
383; GFX9-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x24
384; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
385; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
386; GFX9-NEXT:    global_load_dword v0, v0, s[2:3] glc
387; GFX9-NEXT:    s_waitcnt vmcnt(0)
388; GFX9-NEXT:    s_mov_b32 s3, 0xf000
389; GFX9-NEXT:    s_mov_b32 s2, -1
390; GFX9-NEXT:    v_pk_sub_i16 v0, v0, 32
391; GFX9-NEXT:    buffer_store_dword v0, off, s[0:3], 0
392; GFX9-NEXT:    s_endpgm
393;
394; VI-LABEL: v_test_sub_v2i16_inline_lo_zero_hi:
395; VI:       ; %bb.0:
396; VI-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x24
397; VI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
398; VI-NEXT:    s_waitcnt lgkmcnt(0)
399; VI-NEXT:    v_mov_b32_e32 v1, s3
400; VI-NEXT:    v_add_u32_e32 v0, vcc, s2, v0
401; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
402; VI-NEXT:    flat_load_dword v0, v[0:1] glc
403; VI-NEXT:    s_waitcnt vmcnt(0)
404; VI-NEXT:    s_mov_b32 s3, 0xf000
405; VI-NEXT:    s_mov_b32 s2, -1
406; VI-NEXT:    v_and_b32_e32 v1, 0xffff0000, v0
407; VI-NEXT:    v_subrev_u16_e32 v0, 32, v0
408; VI-NEXT:    v_or_b32_e32 v0, v0, v1
409; VI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
410; VI-NEXT:    s_endpgm
411;
412; GFX10-LABEL: v_test_sub_v2i16_inline_lo_zero_hi:
413; GFX10:       ; %bb.0:
414; GFX10-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x24
415; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
416; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
417; GFX10-NEXT:    global_load_dword v0, v0, s[2:3] glc dlc
418; GFX10-NEXT:    s_waitcnt vmcnt(0)
419; GFX10-NEXT:    s_waitcnt_depctr 0xffe3
420; GFX10-NEXT:    s_mov_b32 s3, 0x31016000
421; GFX10-NEXT:    s_mov_b32 s2, -1
422; GFX10-NEXT:    v_pk_sub_i16 v0, v0, 32
423; GFX10-NEXT:    buffer_store_dword v0, off, s[0:3], 0
424; GFX10-NEXT:    s_endpgm
425  %tid = call i32 @llvm.amdgcn.workitem.id.x()
426  %gep.out = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %out, i32 %tid
427  %gep.in0 = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in0, i32 %tid
428  %a = load volatile <2 x i16>, <2 x i16> addrspace(1)* %gep.in0
429  %add = sub <2 x i16> %a, <i16 32, i16 0>
430  store <2 x i16> %add, <2 x i16> addrspace(1)* %out
431  ret void
432}
433
434; The high element gives fp
435define amdgpu_kernel void @v_test_sub_v2i16_inline_fp_split(<2 x i16> addrspace(1)* %out, <2 x i16> addrspace(1)* %in0) #1 {
436; GFX9-LABEL: v_test_sub_v2i16_inline_fp_split:
437; GFX9:       ; %bb.0:
438; GFX9-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x24
439; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
440; GFX9-NEXT:    s_mov_b32 s4, 1.0
441; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
442; GFX9-NEXT:    global_load_dword v0, v0, s[2:3] glc
443; GFX9-NEXT:    s_waitcnt vmcnt(0)
444; GFX9-NEXT:    s_mov_b32 s3, 0xf000
445; GFX9-NEXT:    s_mov_b32 s2, -1
446; GFX9-NEXT:    v_pk_sub_i16 v0, v0, s4
447; GFX9-NEXT:    buffer_store_dword v0, off, s[0:3], 0
448; GFX9-NEXT:    s_endpgm
449;
450; VI-LABEL: v_test_sub_v2i16_inline_fp_split:
451; VI:       ; %bb.0:
452; VI-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x24
453; VI-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
454; VI-NEXT:    s_waitcnt lgkmcnt(0)
455; VI-NEXT:    v_mov_b32_e32 v1, s3
456; VI-NEXT:    v_add_u32_e32 v0, vcc, s2, v0
457; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
458; VI-NEXT:    flat_load_dword v0, v[0:1] glc
459; VI-NEXT:    s_waitcnt vmcnt(0)
460; VI-NEXT:    v_mov_b32_e32 v1, 0xffffc080
461; VI-NEXT:    s_mov_b32 s3, 0xf000
462; VI-NEXT:    s_mov_b32 s2, -1
463; VI-NEXT:    v_add_u16_sdwa v1, v0, v1 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:DWORD
464; VI-NEXT:    v_or_b32_sdwa v0, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
465; VI-NEXT:    buffer_store_dword v0, off, s[0:3], 0
466; VI-NEXT:    s_endpgm
467;
468; GFX10-LABEL: v_test_sub_v2i16_inline_fp_split:
469; GFX10:       ; %bb.0:
470; GFX10-NEXT:    s_load_dwordx4 s[0:3], s[0:1], 0x24
471; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
472; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
473; GFX10-NEXT:    global_load_dword v0, v0, s[2:3] glc dlc
474; GFX10-NEXT:    s_waitcnt vmcnt(0)
475; GFX10-NEXT:    s_waitcnt_depctr 0xffe3
476; GFX10-NEXT:    s_mov_b32 s3, 0x31016000
477; GFX10-NEXT:    s_mov_b32 s2, -1
478; GFX10-NEXT:    v_pk_sub_i16 v0, v0, 0x3f80 op_sel:[0,1] op_sel_hi:[1,0]
479; GFX10-NEXT:    buffer_store_dword v0, off, s[0:3], 0
480; GFX10-NEXT:    s_endpgm
481  %tid = call i32 @llvm.amdgcn.workitem.id.x()
482  %gep.out = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %out, i32 %tid
483  %gep.in0 = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in0, i32 %tid
484  %a = load volatile <2 x i16>, <2 x i16> addrspace(1)* %gep.in0
485  %add = sub <2 x i16> %a, <i16 0, i16 16256>
486  store <2 x i16> %add, <2 x i16> addrspace(1)* %out
487  ret void
488}
489
490; FIXME: Need to handle non-uniform case for function below (load without gep).
491define amdgpu_kernel void @v_test_sub_v2i16_zext_to_v2i32(<2 x i32> addrspace(1)* %out, <2 x i16> addrspace(1)* %in0, <2 x i16> addrspace(1)* %in1) #1 {
492; GFX9-LABEL: v_test_sub_v2i16_zext_to_v2i32:
493; GFX9:       ; %bb.0:
494; GFX9-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
495; GFX9-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x34
496; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
497; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
498; GFX9-NEXT:    global_load_dword v1, v0, s[6:7] glc
499; GFX9-NEXT:    s_waitcnt vmcnt(0)
500; GFX9-NEXT:    global_load_dword v2, v0, s[2:3] glc
501; GFX9-NEXT:    s_waitcnt vmcnt(0)
502; GFX9-NEXT:    s_mov_b32 s7, 0xf000
503; GFX9-NEXT:    s_mov_b32 s6, -1
504; GFX9-NEXT:    v_pk_sub_i16 v0, v1, v2
505; GFX9-NEXT:    v_lshrrev_b32_e32 v1, 16, v0
506; GFX9-NEXT:    v_and_b32_e32 v0, 0xffff, v0
507; GFX9-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
508; GFX9-NEXT:    s_endpgm
509;
510; VI-LABEL: v_test_sub_v2i16_zext_to_v2i32:
511; VI:       ; %bb.0:
512; VI-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
513; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x34
514; VI-NEXT:    v_lshlrev_b32_e32 v2, 2, v0
515; VI-NEXT:    s_waitcnt lgkmcnt(0)
516; VI-NEXT:    v_mov_b32_e32 v1, s7
517; VI-NEXT:    v_add_u32_e32 v0, vcc, s6, v2
518; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
519; VI-NEXT:    v_mov_b32_e32 v3, s1
520; VI-NEXT:    v_add_u32_e32 v2, vcc, s0, v2
521; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v3, vcc
522; VI-NEXT:    flat_load_dword v1, v[0:1] glc
523; VI-NEXT:    s_waitcnt vmcnt(0)
524; VI-NEXT:    flat_load_dword v2, v[2:3] glc
525; VI-NEXT:    s_waitcnt vmcnt(0)
526; VI-NEXT:    s_mov_b32 s7, 0xf000
527; VI-NEXT:    s_mov_b32 s6, -1
528; VI-NEXT:    v_sub_u16_e32 v0, v1, v2
529; VI-NEXT:    v_sub_u16_sdwa v1, v1, v2 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:WORD_1
530; VI-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
531; VI-NEXT:    s_endpgm
532;
533; GFX10-LABEL: v_test_sub_v2i16_zext_to_v2i32:
534; GFX10:       ; %bb.0:
535; GFX10-NEXT:    s_clause 0x1
536; GFX10-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
537; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x34
538; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
539; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
540; GFX10-NEXT:    global_load_dword v1, v0, s[6:7] glc dlc
541; GFX10-NEXT:    s_waitcnt vmcnt(0)
542; GFX10-NEXT:    global_load_dword v2, v0, s[2:3] glc dlc
543; GFX10-NEXT:    s_waitcnt vmcnt(0)
544; GFX10-NEXT:    s_waitcnt_depctr 0xffe3
545; GFX10-NEXT:    s_mov_b32 s7, 0x31016000
546; GFX10-NEXT:    s_mov_b32 s6, -1
547; GFX10-NEXT:    v_pk_sub_i16 v0, v1, v2
548; GFX10-NEXT:    v_lshrrev_b32_e32 v1, 16, v0
549; GFX10-NEXT:    v_and_b32_e32 v0, 0xffff, v0
550; GFX10-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
551; GFX10-NEXT:    s_endpgm
552  %tid = call i32 @llvm.amdgcn.workitem.id.x()
553  %gep.out = getelementptr inbounds <2 x i32>, <2 x i32> addrspace(1)* %out, i32 %tid
554  %gep.in0 = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in0, i32 %tid
555  %gep.in1 = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in1, i32 %tid
556  %a = load volatile <2 x i16>, <2 x i16> addrspace(1)* %gep.in0
557  %b = load volatile <2 x i16>, <2 x i16> addrspace(1)* %gep.in1
558  %add = sub <2 x i16> %a, %b
559  %ext = zext <2 x i16> %add to <2 x i32>
560  store <2 x i32> %ext, <2 x i32> addrspace(1)* %out
561  ret void
562}
563
564; FIXME: Need to handle non-uniform case for function below (load without gep).
565define amdgpu_kernel void @v_test_sub_v2i16_zext_to_v2i64(<2 x i64> addrspace(1)* %out, <2 x i16> addrspace(1)* %in0, <2 x i16> addrspace(1)* %in1) #1 {
566; GFX9-LABEL: v_test_sub_v2i16_zext_to_v2i64:
567; GFX9:       ; %bb.0:
568; GFX9-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
569; GFX9-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x34
570; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
571; GFX9-NEXT:    v_mov_b32_e32 v4, 0xffff
572; GFX9-NEXT:    v_mov_b32_e32 v1, 0
573; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
574; GFX9-NEXT:    global_load_dword v2, v0, s[6:7] glc
575; GFX9-NEXT:    s_waitcnt vmcnt(0)
576; GFX9-NEXT:    global_load_dword v3, v0, s[2:3] glc
577; GFX9-NEXT:    s_waitcnt vmcnt(0)
578; GFX9-NEXT:    s_mov_b32 s7, 0xf000
579; GFX9-NEXT:    s_mov_b32 s6, -1
580; GFX9-NEXT:    v_pk_sub_i16 v2, v2, v3
581; GFX9-NEXT:    v_and_b32_e32 v0, v4, v2
582; GFX9-NEXT:    v_and_b32_sdwa v2, v4, v2 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
583; GFX9-NEXT:    v_mov_b32_e32 v3, v1
584; GFX9-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
585; GFX9-NEXT:    s_endpgm
586;
587; VI-LABEL: v_test_sub_v2i16_zext_to_v2i64:
588; VI:       ; %bb.0:
589; VI-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
590; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x34
591; VI-NEXT:    v_lshlrev_b32_e32 v2, 2, v0
592; VI-NEXT:    s_waitcnt lgkmcnt(0)
593; VI-NEXT:    v_mov_b32_e32 v1, s7
594; VI-NEXT:    v_add_u32_e32 v0, vcc, s6, v2
595; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
596; VI-NEXT:    v_mov_b32_e32 v3, s1
597; VI-NEXT:    v_add_u32_e32 v2, vcc, s0, v2
598; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v3, vcc
599; VI-NEXT:    flat_load_dword v4, v[0:1] glc
600; VI-NEXT:    s_waitcnt vmcnt(0)
601; VI-NEXT:    flat_load_dword v2, v[2:3] glc
602; VI-NEXT:    s_waitcnt vmcnt(0)
603; VI-NEXT:    v_mov_b32_e32 v1, 0
604; VI-NEXT:    s_mov_b32 s7, 0xf000
605; VI-NEXT:    s_mov_b32 s6, -1
606; VI-NEXT:    v_mov_b32_e32 v3, v1
607; VI-NEXT:    v_sub_u16_e32 v0, v4, v2
608; VI-NEXT:    v_sub_u16_sdwa v2, v4, v2 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:WORD_1
609; VI-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
610; VI-NEXT:    s_endpgm
611;
612; GFX10-LABEL: v_test_sub_v2i16_zext_to_v2i64:
613; GFX10:       ; %bb.0:
614; GFX10-NEXT:    s_clause 0x1
615; GFX10-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
616; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x34
617; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
618; GFX10-NEXT:    v_mov_b32_e32 v3, 0xffff
619; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
620; GFX10-NEXT:    global_load_dword v1, v0, s[6:7] glc dlc
621; GFX10-NEXT:    s_waitcnt vmcnt(0)
622; GFX10-NEXT:    global_load_dword v2, v0, s[2:3] glc dlc
623; GFX10-NEXT:    s_waitcnt vmcnt(0)
624; GFX10-NEXT:    s_waitcnt_depctr 0xffe3
625; GFX10-NEXT:    s_mov_b32 s7, 0x31016000
626; GFX10-NEXT:    s_mov_b32 s6, -1
627; GFX10-NEXT:    v_pk_sub_i16 v2, v1, v2
628; GFX10-NEXT:    v_mov_b32_e32 v1, 0
629; GFX10-NEXT:    v_and_b32_e32 v0, v3, v2
630; GFX10-NEXT:    v_and_b32_sdwa v2, v3, v2 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_1
631; GFX10-NEXT:    v_mov_b32_e32 v3, v1
632; GFX10-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
633; GFX10-NEXT:    s_endpgm
634  %tid = call i32 @llvm.amdgcn.workitem.id.x()
635  %gep.out = getelementptr inbounds <2 x i64>, <2 x i64> addrspace(1)* %out, i32 %tid
636  %gep.in0 = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in0, i32 %tid
637  %gep.in1 = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in1, i32 %tid
638  %a = load volatile <2 x i16>, <2 x i16> addrspace(1)* %gep.in0
639  %b = load volatile <2 x i16>, <2 x i16> addrspace(1)* %gep.in1
640  %add = sub <2 x i16> %a, %b
641  %ext = zext <2 x i16> %add to <2 x i64>
642  store <2 x i64> %ext, <2 x i64> addrspace(1)* %out
643  ret void
644}
645
646; FIXME: Need to handle non-uniform case for function below (load without gep).
647define amdgpu_kernel void @v_test_sub_v2i16_sext_to_v2i32(<2 x i32> addrspace(1)* %out, <2 x i16> addrspace(1)* %in0, <2 x i16> addrspace(1)* %in1) #1 {
648; GFX9-LABEL: v_test_sub_v2i16_sext_to_v2i32:
649; GFX9:       ; %bb.0:
650; GFX9-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
651; GFX9-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x34
652; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
653; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
654; GFX9-NEXT:    global_load_dword v1, v0, s[6:7] glc
655; GFX9-NEXT:    s_waitcnt vmcnt(0)
656; GFX9-NEXT:    global_load_dword v2, v0, s[2:3] glc
657; GFX9-NEXT:    s_waitcnt vmcnt(0)
658; GFX9-NEXT:    s_mov_b32 s7, 0xf000
659; GFX9-NEXT:    s_mov_b32 s6, -1
660; GFX9-NEXT:    v_pk_sub_i16 v0, v1, v2
661; GFX9-NEXT:    v_ashrrev_i32_e32 v1, 16, v0
662; GFX9-NEXT:    v_bfe_i32 v0, v0, 0, 16
663; GFX9-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
664; GFX9-NEXT:    s_endpgm
665;
666; VI-LABEL: v_test_sub_v2i16_sext_to_v2i32:
667; VI:       ; %bb.0:
668; VI-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
669; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x34
670; VI-NEXT:    v_lshlrev_b32_e32 v2, 2, v0
671; VI-NEXT:    s_waitcnt lgkmcnt(0)
672; VI-NEXT:    v_mov_b32_e32 v1, s7
673; VI-NEXT:    v_add_u32_e32 v0, vcc, s6, v2
674; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
675; VI-NEXT:    v_mov_b32_e32 v3, s1
676; VI-NEXT:    v_add_u32_e32 v2, vcc, s0, v2
677; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v3, vcc
678; VI-NEXT:    flat_load_dword v0, v[0:1] glc
679; VI-NEXT:    s_waitcnt vmcnt(0)
680; VI-NEXT:    flat_load_dword v1, v[2:3] glc
681; VI-NEXT:    s_waitcnt vmcnt(0)
682; VI-NEXT:    s_mov_b32 s7, 0xf000
683; VI-NEXT:    s_mov_b32 s6, -1
684; VI-NEXT:    v_sub_u16_sdwa v2, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:WORD_1
685; VI-NEXT:    v_sub_u16_e32 v0, v0, v1
686; VI-NEXT:    v_bfe_i32 v0, v0, 0, 16
687; VI-NEXT:    v_bfe_i32 v1, v2, 0, 16
688; VI-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
689; VI-NEXT:    s_endpgm
690;
691; GFX10-LABEL: v_test_sub_v2i16_sext_to_v2i32:
692; GFX10:       ; %bb.0:
693; GFX10-NEXT:    s_clause 0x1
694; GFX10-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
695; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x34
696; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
697; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
698; GFX10-NEXT:    global_load_dword v1, v0, s[6:7] glc dlc
699; GFX10-NEXT:    s_waitcnt vmcnt(0)
700; GFX10-NEXT:    global_load_dword v2, v0, s[2:3] glc dlc
701; GFX10-NEXT:    s_waitcnt vmcnt(0)
702; GFX10-NEXT:    s_waitcnt_depctr 0xffe3
703; GFX10-NEXT:    s_mov_b32 s7, 0x31016000
704; GFX10-NEXT:    s_mov_b32 s6, -1
705; GFX10-NEXT:    v_pk_sub_i16 v0, v1, v2
706; GFX10-NEXT:    v_ashrrev_i32_e32 v1, 16, v0
707; GFX10-NEXT:    v_bfe_i32 v0, v0, 0, 16
708; GFX10-NEXT:    buffer_store_dwordx2 v[0:1], off, s[4:7], 0
709; GFX10-NEXT:    s_endpgm
710  %tid = call i32 @llvm.amdgcn.workitem.id.x()
711  %gep.out = getelementptr inbounds <2 x i32>, <2 x i32> addrspace(1)* %out, i32 %tid
712  %gep.in0 = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in0, i32 %tid
713  %gep.in1 = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in1, i32 %tid
714  %a = load volatile <2 x i16>, <2 x i16> addrspace(1)* %gep.in0
715  %b = load volatile <2 x i16>, <2 x i16> addrspace(1)* %gep.in1
716  %add = sub <2 x i16> %a, %b
717  %ext = sext <2 x i16> %add to <2 x i32>
718  store <2 x i32> %ext, <2 x i32> addrspace(1)* %out
719  ret void
720}
721
722; FIXME: Need to handle non-uniform case for function below (load without gep).
723define amdgpu_kernel void @v_test_sub_v2i16_sext_to_v2i64(<2 x i64> addrspace(1)* %out, <2 x i16> addrspace(1)* %in0, <2 x i16> addrspace(1)* %in1) #1 {
724; GFX9-LABEL: v_test_sub_v2i16_sext_to_v2i64:
725; GFX9:       ; %bb.0:
726; GFX9-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
727; GFX9-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x34
728; GFX9-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
729; GFX9-NEXT:    s_waitcnt lgkmcnt(0)
730; GFX9-NEXT:    global_load_dword v1, v0, s[6:7]
731; GFX9-NEXT:    global_load_dword v2, v0, s[2:3]
732; GFX9-NEXT:    s_mov_b32 s7, 0xf000
733; GFX9-NEXT:    s_mov_b32 s6, -1
734; GFX9-NEXT:    s_waitcnt vmcnt(0)
735; GFX9-NEXT:    v_pk_sub_i16 v1, v1, v2
736; GFX9-NEXT:    v_lshrrev_b32_e32 v2, 16, v1
737; GFX9-NEXT:    v_bfe_i32 v0, v1, 0, 16
738; GFX9-NEXT:    v_bfe_i32 v2, v2, 0, 16
739; GFX9-NEXT:    v_ashrrev_i32_e32 v1, 31, v0
740; GFX9-NEXT:    v_ashrrev_i32_e32 v3, 31, v2
741; GFX9-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
742; GFX9-NEXT:    s_endpgm
743;
744; VI-LABEL: v_test_sub_v2i16_sext_to_v2i64:
745; VI:       ; %bb.0:
746; VI-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
747; VI-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x34
748; VI-NEXT:    v_lshlrev_b32_e32 v2, 2, v0
749; VI-NEXT:    s_waitcnt lgkmcnt(0)
750; VI-NEXT:    v_mov_b32_e32 v1, s7
751; VI-NEXT:    v_add_u32_e32 v0, vcc, s6, v2
752; VI-NEXT:    v_addc_u32_e32 v1, vcc, 0, v1, vcc
753; VI-NEXT:    v_mov_b32_e32 v3, s1
754; VI-NEXT:    v_add_u32_e32 v2, vcc, s0, v2
755; VI-NEXT:    v_addc_u32_e32 v3, vcc, 0, v3, vcc
756; VI-NEXT:    flat_load_dword v0, v[0:1]
757; VI-NEXT:    flat_load_dword v1, v[2:3]
758; VI-NEXT:    s_mov_b32 s7, 0xf000
759; VI-NEXT:    s_mov_b32 s6, -1
760; VI-NEXT:    s_waitcnt vmcnt(0)
761; VI-NEXT:    v_sub_u16_sdwa v2, v0, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:WORD_1
762; VI-NEXT:    v_sub_u16_e32 v0, v0, v1
763; VI-NEXT:    v_bfe_i32 v0, v0, 0, 16
764; VI-NEXT:    v_bfe_i32 v2, v2, 0, 16
765; VI-NEXT:    v_ashrrev_i32_e32 v1, 31, v0
766; VI-NEXT:    v_ashrrev_i32_e32 v3, 31, v2
767; VI-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
768; VI-NEXT:    s_endpgm
769;
770; GFX10-LABEL: v_test_sub_v2i16_sext_to_v2i64:
771; GFX10:       ; %bb.0:
772; GFX10-NEXT:    s_clause 0x1
773; GFX10-NEXT:    s_load_dwordx4 s[4:7], s[0:1], 0x24
774; GFX10-NEXT:    s_load_dwordx2 s[2:3], s[0:1], 0x34
775; GFX10-NEXT:    v_lshlrev_b32_e32 v0, 2, v0
776; GFX10-NEXT:    s_waitcnt lgkmcnt(0)
777; GFX10-NEXT:    s_clause 0x1
778; GFX10-NEXT:    global_load_dword v1, v0, s[6:7]
779; GFX10-NEXT:    global_load_dword v2, v0, s[2:3]
780; GFX10-NEXT:    s_waitcnt_depctr 0xffe3
781; GFX10-NEXT:    s_mov_b32 s7, 0x31016000
782; GFX10-NEXT:    s_mov_b32 s6, -1
783; GFX10-NEXT:    s_waitcnt vmcnt(0)
784; GFX10-NEXT:    v_pk_sub_i16 v0, v1, v2
785; GFX10-NEXT:    v_lshrrev_b32_e32 v1, 16, v0
786; GFX10-NEXT:    v_bfe_i32 v0, v0, 0, 16
787; GFX10-NEXT:    v_bfe_i32 v2, v1, 0, 16
788; GFX10-NEXT:    v_ashrrev_i32_e32 v1, 31, v0
789; GFX10-NEXT:    v_ashrrev_i32_e32 v3, 31, v2
790; GFX10-NEXT:    buffer_store_dwordx4 v[0:3], off, s[4:7], 0
791; GFX10-NEXT:    s_endpgm
792  %tid = call i32 @llvm.amdgcn.workitem.id.x()
793  %gep.out = getelementptr inbounds <2 x i64>, <2 x i64> addrspace(1)* %out, i32 %tid
794  %gep.in0 = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in0, i32 %tid
795  %gep.in1 = getelementptr inbounds <2 x i16>, <2 x i16> addrspace(1)* %in1, i32 %tid
796  %a = load <2 x i16>, <2 x i16> addrspace(1)* %gep.in0
797  %b = load <2 x i16>, <2 x i16> addrspace(1)* %gep.in1
798  %add = sub <2 x i16> %a, %b
799  %ext = sext <2 x i16> %add to <2 x i64>
800  store <2 x i64> %ext, <2 x i64> addrspace(1)* %out
801  ret void
802}
803
804declare i32 @llvm.amdgcn.workitem.id.x() #0
805
806attributes #0 = { nounwind readnone }
807attributes #1 = { nounwind }
808