1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=tahiti < %s | FileCheck --check-prefix=GFX6 %s
3; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=fiji < %s | FileCheck --check-prefix=GFX8 %s
4; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx900 < %s | FileCheck --check-prefix=GFX9 %s
5; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx1010 < %s | FileCheck --check-prefix=GFX10 %s
6
7define i8 @v_saddsat_i8(i8 %lhs, i8 %rhs) {
8; GFX6-LABEL: v_saddsat_i8:
9; GFX6:       ; %bb.0:
10; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
11; GFX6-NEXT:    v_bfe_i32 v1, v1, 0, 8
12; GFX6-NEXT:    v_bfe_i32 v0, v0, 0, 8
13; GFX6-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
14; GFX6-NEXT:    v_min_i32_e32 v0, 0x7f, v0
15; GFX6-NEXT:    v_max_i32_e32 v0, 0xffffff80, v0
16; GFX6-NEXT:    s_setpc_b64 s[30:31]
17;
18; GFX8-LABEL: v_saddsat_i8:
19; GFX8:       ; %bb.0:
20; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
21; GFX8-NEXT:    v_add_u16_sdwa v0, sext(v0), sext(v1) dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:BYTE_0
22; GFX8-NEXT:    v_min_i16_e32 v0, 0x7f, v0
23; GFX8-NEXT:    v_max_i16_e32 v0, 0xff80, v0
24; GFX8-NEXT:    s_setpc_b64 s[30:31]
25;
26; GFX9-LABEL: v_saddsat_i8:
27; GFX9:       ; %bb.0:
28; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
29; GFX9-NEXT:    v_lshlrev_b16_e32 v1, 8, v1
30; GFX9-NEXT:    v_lshlrev_b16_e32 v0, 8, v0
31; GFX9-NEXT:    v_add_i16 v0, v0, v1 clamp
32; GFX9-NEXT:    v_ashrrev_i16_e32 v0, 8, v0
33; GFX9-NEXT:    s_setpc_b64 s[30:31]
34;
35; GFX10-LABEL: v_saddsat_i8:
36; GFX10:       ; %bb.0:
37; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
38; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
39; GFX10-NEXT:    v_lshlrev_b16 v1, 8, v1
40; GFX10-NEXT:    v_lshlrev_b16 v0, 8, v0
41; GFX10-NEXT:    v_add_nc_i16 v0, v0, v1 clamp
42; GFX10-NEXT:    v_ashrrev_i16 v0, 8, v0
43; GFX10-NEXT:    s_setpc_b64 s[30:31]
44  %result = call i8 @llvm.sadd.sat.i8(i8 %lhs, i8 %rhs)
45  ret i8 %result
46}
47
48define i16 @v_saddsat_i16(i16 %lhs, i16 %rhs) {
49; GFX6-LABEL: v_saddsat_i16:
50; GFX6:       ; %bb.0:
51; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
52; GFX6-NEXT:    v_bfe_i32 v1, v1, 0, 16
53; GFX6-NEXT:    v_bfe_i32 v0, v0, 0, 16
54; GFX6-NEXT:    v_add_i32_e32 v0, vcc, v0, v1
55; GFX6-NEXT:    v_min_i32_e32 v0, 0x7fff, v0
56; GFX6-NEXT:    v_max_i32_e32 v0, 0xffff8000, v0
57; GFX6-NEXT:    s_setpc_b64 s[30:31]
58;
59; GFX8-LABEL: v_saddsat_i16:
60; GFX8:       ; %bb.0:
61; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
62; GFX8-NEXT:    v_cmp_gt_i16_e32 vcc, 0, v1
63; GFX8-NEXT:    v_add_u16_e32 v1, v0, v1
64; GFX8-NEXT:    v_cmp_lt_i16_e64 s[4:5], v1, v0
65; GFX8-NEXT:    v_mov_b32_e32 v0, 0xffff8000
66; GFX8-NEXT:    v_mov_b32_e32 v2, 0x7fff
67; GFX8-NEXT:    v_cmp_gt_i16_e64 s[6:7], 0, v1
68; GFX8-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[6:7]
69; GFX8-NEXT:    s_xor_b64 vcc, vcc, s[4:5]
70; GFX8-NEXT:    v_cndmask_b32_e32 v0, v1, v0, vcc
71; GFX8-NEXT:    s_setpc_b64 s[30:31]
72;
73; GFX9-LABEL: v_saddsat_i16:
74; GFX9:       ; %bb.0:
75; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
76; GFX9-NEXT:    v_add_i16 v0, v0, v1 clamp
77; GFX9-NEXT:    s_setpc_b64 s[30:31]
78;
79; GFX10-LABEL: v_saddsat_i16:
80; GFX10:       ; %bb.0:
81; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
82; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
83; GFX10-NEXT:    v_add_nc_i16 v0, v0, v1 clamp
84; GFX10-NEXT:    s_setpc_b64 s[30:31]
85  %result = call i16 @llvm.sadd.sat.i16(i16 %lhs, i16 %rhs)
86  ret i16 %result
87}
88
89define i32 @v_saddsat_i32(i32 %lhs, i32 %rhs) {
90; GFX6-LABEL: v_saddsat_i32:
91; GFX6:       ; %bb.0:
92; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
93; GFX6-NEXT:    v_cmp_gt_i32_e32 vcc, 0, v1
94; GFX6-NEXT:    v_add_i32_e64 v1, s[4:5], v0, v1
95; GFX6-NEXT:    v_cmp_lt_i32_e64 s[4:5], v1, v0
96; GFX6-NEXT:    v_bfrev_b32_e32 v0, 1
97; GFX6-NEXT:    v_bfrev_b32_e32 v2, -2
98; GFX6-NEXT:    v_cmp_gt_i32_e64 s[6:7], 0, v1
99; GFX6-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[6:7]
100; GFX6-NEXT:    s_xor_b64 vcc, vcc, s[4:5]
101; GFX6-NEXT:    v_cndmask_b32_e32 v0, v1, v0, vcc
102; GFX6-NEXT:    s_setpc_b64 s[30:31]
103;
104; GFX8-LABEL: v_saddsat_i32:
105; GFX8:       ; %bb.0:
106; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
107; GFX8-NEXT:    v_cmp_gt_i32_e32 vcc, 0, v1
108; GFX8-NEXT:    v_add_u32_e64 v1, s[4:5], v0, v1
109; GFX8-NEXT:    v_cmp_lt_i32_e64 s[4:5], v1, v0
110; GFX8-NEXT:    v_bfrev_b32_e32 v0, 1
111; GFX8-NEXT:    v_bfrev_b32_e32 v2, -2
112; GFX8-NEXT:    v_cmp_gt_i32_e64 s[6:7], 0, v1
113; GFX8-NEXT:    v_cndmask_b32_e64 v0, v0, v2, s[6:7]
114; GFX8-NEXT:    s_xor_b64 vcc, vcc, s[4:5]
115; GFX8-NEXT:    v_cndmask_b32_e32 v0, v1, v0, vcc
116; GFX8-NEXT:    s_setpc_b64 s[30:31]
117;
118; GFX9-LABEL: v_saddsat_i32:
119; GFX9:       ; %bb.0:
120; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
121; GFX9-NEXT:    v_add_i32 v0, v0, v1 clamp
122; GFX9-NEXT:    s_setpc_b64 s[30:31]
123;
124; GFX10-LABEL: v_saddsat_i32:
125; GFX10:       ; %bb.0:
126; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
127; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
128; GFX10-NEXT:    v_add_nc_i32 v0, v0, v1 clamp
129; GFX10-NEXT:    s_setpc_b64 s[30:31]
130  %result = call i32 @llvm.sadd.sat.i32(i32 %lhs, i32 %rhs)
131  ret i32 %result
132}
133
134define <2 x i16> @v_saddsat_v2i16(<2 x i16> %lhs, <2 x i16> %rhs) {
135; GFX6-LABEL: v_saddsat_v2i16:
136; GFX6:       ; %bb.0:
137; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
138; GFX6-NEXT:    v_bfe_i32 v2, v2, 0, 16
139; GFX6-NEXT:    v_bfe_i32 v0, v0, 0, 16
140; GFX6-NEXT:    v_bfe_i32 v3, v3, 0, 16
141; GFX6-NEXT:    v_bfe_i32 v1, v1, 0, 16
142; GFX6-NEXT:    v_add_i32_e32 v1, vcc, v1, v3
143; GFX6-NEXT:    s_movk_i32 s4, 0x7fff
144; GFX6-NEXT:    v_add_i32_e32 v0, vcc, v0, v2
145; GFX6-NEXT:    v_min_i32_e32 v1, s4, v1
146; GFX6-NEXT:    s_movk_i32 s5, 0x8000
147; GFX6-NEXT:    v_min_i32_e32 v0, s4, v0
148; GFX6-NEXT:    v_max_i32_e32 v1, s5, v1
149; GFX6-NEXT:    v_max_i32_e32 v0, s5, v0
150; GFX6-NEXT:    v_lshlrev_b32_e32 v1, 16, v1
151; GFX6-NEXT:    v_and_b32_e32 v0, 0xffff, v0
152; GFX6-NEXT:    v_or_b32_e32 v0, v0, v1
153; GFX6-NEXT:    v_lshrrev_b32_e32 v1, 16, v0
154; GFX6-NEXT:    s_setpc_b64 s[30:31]
155;
156; GFX8-LABEL: v_saddsat_v2i16:
157; GFX8:       ; %bb.0:
158; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
159; GFX8-NEXT:    v_lshrrev_b32_e32 v2, 16, v1
160; GFX8-NEXT:    v_lshrrev_b32_e32 v3, 16, v0
161; GFX8-NEXT:    v_add_u16_e32 v4, v3, v2
162; GFX8-NEXT:    v_mov_b32_e32 v5, 0xffff8000
163; GFX8-NEXT:    v_mov_b32_e32 v6, 0x7fff
164; GFX8-NEXT:    v_cmp_gt_i16_e32 vcc, 0, v4
165; GFX8-NEXT:    v_cndmask_b32_e32 v7, v5, v6, vcc
166; GFX8-NEXT:    v_cmp_lt_i16_e32 vcc, v4, v3
167; GFX8-NEXT:    v_cmp_gt_i16_e64 s[4:5], 0, v2
168; GFX8-NEXT:    s_xor_b64 vcc, s[4:5], vcc
169; GFX8-NEXT:    v_cndmask_b32_e32 v2, v4, v7, vcc
170; GFX8-NEXT:    v_cmp_gt_i16_e32 vcc, 0, v1
171; GFX8-NEXT:    v_add_u16_e32 v1, v0, v1
172; GFX8-NEXT:    v_cmp_lt_i16_e64 s[4:5], v1, v0
173; GFX8-NEXT:    v_cmp_gt_i16_e64 s[6:7], 0, v1
174; GFX8-NEXT:    v_cndmask_b32_e64 v0, v5, v6, s[6:7]
175; GFX8-NEXT:    s_xor_b64 vcc, vcc, s[4:5]
176; GFX8-NEXT:    v_lshlrev_b32_e32 v2, 16, v2
177; GFX8-NEXT:    v_cndmask_b32_e32 v0, v1, v0, vcc
178; GFX8-NEXT:    v_or_b32_sdwa v0, v0, v2 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
179; GFX8-NEXT:    s_setpc_b64 s[30:31]
180;
181; GFX9-LABEL: v_saddsat_v2i16:
182; GFX9:       ; %bb.0:
183; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
184; GFX9-NEXT:    v_pk_add_i16 v0, v0, v1 clamp
185; GFX9-NEXT:    s_setpc_b64 s[30:31]
186;
187; GFX10-LABEL: v_saddsat_v2i16:
188; GFX10:       ; %bb.0:
189; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
190; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
191; GFX10-NEXT:    v_pk_add_i16 v0, v0, v1 clamp
192; GFX10-NEXT:    s_setpc_b64 s[30:31]
193  %result = call <2 x i16> @llvm.sadd.sat.v2i16(<2 x i16> %lhs, <2 x i16> %rhs)
194  ret <2 x i16> %result
195}
196
197define <3 x i16> @v_saddsat_v3i16(<3 x i16> %lhs, <3 x i16> %rhs) {
198; GFX6-LABEL: v_saddsat_v3i16:
199; GFX6:       ; %bb.0:
200; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
201; GFX6-NEXT:    v_bfe_i32 v3, v3, 0, 16
202; GFX6-NEXT:    v_bfe_i32 v0, v0, 0, 16
203; GFX6-NEXT:    v_bfe_i32 v4, v4, 0, 16
204; GFX6-NEXT:    v_bfe_i32 v1, v1, 0, 16
205; GFX6-NEXT:    v_bfe_i32 v5, v5, 0, 16
206; GFX6-NEXT:    v_bfe_i32 v2, v2, 0, 16
207; GFX6-NEXT:    v_add_i32_e32 v1, vcc, v1, v4
208; GFX6-NEXT:    s_movk_i32 s4, 0x7fff
209; GFX6-NEXT:    v_add_i32_e32 v0, vcc, v0, v3
210; GFX6-NEXT:    v_add_i32_e32 v2, vcc, v2, v5
211; GFX6-NEXT:    v_min_i32_e32 v1, s4, v1
212; GFX6-NEXT:    s_movk_i32 s5, 0x8000
213; GFX6-NEXT:    v_min_i32_e32 v0, s4, v0
214; GFX6-NEXT:    v_max_i32_e32 v1, s5, v1
215; GFX6-NEXT:    v_max_i32_e32 v0, s5, v0
216; GFX6-NEXT:    v_min_i32_e32 v2, s4, v2
217; GFX6-NEXT:    v_max_i32_e32 v3, s5, v2
218; GFX6-NEXT:    v_lshlrev_b32_e32 v1, 16, v1
219; GFX6-NEXT:    v_and_b32_e32 v0, 0xffff, v0
220; GFX6-NEXT:    v_or_b32_e32 v0, v0, v1
221; GFX6-NEXT:    v_or_b32_e32 v2, 0xffff0000, v3
222; GFX6-NEXT:    v_alignbit_b32 v1, v3, v1, 16
223; GFX6-NEXT:    s_setpc_b64 s[30:31]
224;
225; GFX8-LABEL: v_saddsat_v3i16:
226; GFX8:       ; %bb.0:
227; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
228; GFX8-NEXT:    v_lshrrev_b32_e32 v4, 16, v2
229; GFX8-NEXT:    v_lshrrev_b32_e32 v5, 16, v0
230; GFX8-NEXT:    v_add_u16_e32 v6, v5, v4
231; GFX8-NEXT:    v_mov_b32_e32 v7, 0xffff8000
232; GFX8-NEXT:    v_mov_b32_e32 v8, 0x7fff
233; GFX8-NEXT:    v_cmp_gt_i16_e32 vcc, 0, v6
234; GFX8-NEXT:    v_cndmask_b32_e32 v9, v7, v8, vcc
235; GFX8-NEXT:    v_cmp_lt_i16_e32 vcc, v6, v5
236; GFX8-NEXT:    v_cmp_gt_i16_e64 s[4:5], 0, v4
237; GFX8-NEXT:    s_xor_b64 vcc, s[4:5], vcc
238; GFX8-NEXT:    v_cndmask_b32_e32 v4, v6, v9, vcc
239; GFX8-NEXT:    v_cmp_gt_i16_e32 vcc, 0, v3
240; GFX8-NEXT:    v_add_u16_e32 v3, v1, v3
241; GFX8-NEXT:    v_cmp_lt_i16_e64 s[4:5], v3, v1
242; GFX8-NEXT:    v_cmp_gt_i16_e64 s[6:7], 0, v3
243; GFX8-NEXT:    v_cndmask_b32_e64 v1, v7, v8, s[6:7]
244; GFX8-NEXT:    s_xor_b64 vcc, vcc, s[4:5]
245; GFX8-NEXT:    v_cndmask_b32_e32 v1, v3, v1, vcc
246; GFX8-NEXT:    v_cmp_gt_i16_e32 vcc, 0, v2
247; GFX8-NEXT:    v_add_u16_e32 v2, v0, v2
248; GFX8-NEXT:    v_cmp_lt_i16_e64 s[4:5], v2, v0
249; GFX8-NEXT:    v_cmp_gt_i16_e64 s[6:7], 0, v2
250; GFX8-NEXT:    v_cndmask_b32_e64 v0, v7, v8, s[6:7]
251; GFX8-NEXT:    s_xor_b64 vcc, vcc, s[4:5]
252; GFX8-NEXT:    v_cndmask_b32_e32 v0, v2, v0, vcc
253; GFX8-NEXT:    v_lshlrev_b32_e32 v2, 16, v4
254; GFX8-NEXT:    v_or_b32_sdwa v0, v0, v2 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
255; GFX8-NEXT:    s_setpc_b64 s[30:31]
256;
257; GFX9-LABEL: v_saddsat_v3i16:
258; GFX9:       ; %bb.0:
259; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
260; GFX9-NEXT:    v_pk_add_i16 v1, v1, v3 clamp
261; GFX9-NEXT:    v_pk_add_i16 v0, v0, v2 clamp
262; GFX9-NEXT:    s_setpc_b64 s[30:31]
263;
264; GFX10-LABEL: v_saddsat_v3i16:
265; GFX10:       ; %bb.0:
266; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
267; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
268; GFX10-NEXT:    v_pk_add_i16 v0, v0, v2 clamp
269; GFX10-NEXT:    v_pk_add_i16 v1, v1, v3 clamp
270; GFX10-NEXT:    s_setpc_b64 s[30:31]
271  %result = call <3 x i16> @llvm.sadd.sat.v3i16(<3 x i16> %lhs, <3 x i16> %rhs)
272  ret <3 x i16> %result
273}
274
275define <2 x float> @v_saddsat_v4i16(<4 x i16> %lhs, <4 x i16> %rhs) {
276; GFX6-LABEL: v_saddsat_v4i16:
277; GFX6:       ; %bb.0:
278; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
279; GFX6-NEXT:    v_bfe_i32 v4, v4, 0, 16
280; GFX6-NEXT:    v_bfe_i32 v0, v0, 0, 16
281; GFX6-NEXT:    v_bfe_i32 v5, v5, 0, 16
282; GFX6-NEXT:    v_bfe_i32 v1, v1, 0, 16
283; GFX6-NEXT:    v_add_i32_e32 v1, vcc, v1, v5
284; GFX6-NEXT:    s_movk_i32 s4, 0x7fff
285; GFX6-NEXT:    v_add_i32_e32 v0, vcc, v0, v4
286; GFX6-NEXT:    v_min_i32_e32 v1, s4, v1
287; GFX6-NEXT:    s_movk_i32 s5, 0x8000
288; GFX6-NEXT:    v_min_i32_e32 v0, s4, v0
289; GFX6-NEXT:    v_max_i32_e32 v1, s5, v1
290; GFX6-NEXT:    v_max_i32_e32 v0, s5, v0
291; GFX6-NEXT:    s_mov_b32 s6, 0xffff
292; GFX6-NEXT:    v_bfe_i32 v6, v6, 0, 16
293; GFX6-NEXT:    v_bfe_i32 v2, v2, 0, 16
294; GFX6-NEXT:    v_bfe_i32 v7, v7, 0, 16
295; GFX6-NEXT:    v_bfe_i32 v3, v3, 0, 16
296; GFX6-NEXT:    v_lshlrev_b32_e32 v1, 16, v1
297; GFX6-NEXT:    v_and_b32_e32 v0, s6, v0
298; GFX6-NEXT:    v_add_i32_e32 v2, vcc, v2, v6
299; GFX6-NEXT:    v_or_b32_e32 v0, v0, v1
300; GFX6-NEXT:    v_add_i32_e32 v1, vcc, v3, v7
301; GFX6-NEXT:    v_min_i32_e32 v1, s4, v1
302; GFX6-NEXT:    v_min_i32_e32 v2, s4, v2
303; GFX6-NEXT:    v_max_i32_e32 v1, s5, v1
304; GFX6-NEXT:    v_max_i32_e32 v2, s5, v2
305; GFX6-NEXT:    v_lshlrev_b32_e32 v1, 16, v1
306; GFX6-NEXT:    v_and_b32_e32 v2, s6, v2
307; GFX6-NEXT:    v_or_b32_e32 v1, v2, v1
308; GFX6-NEXT:    s_setpc_b64 s[30:31]
309;
310; GFX8-LABEL: v_saddsat_v4i16:
311; GFX8:       ; %bb.0:
312; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
313; GFX8-NEXT:    v_lshrrev_b32_e32 v4, 16, v2
314; GFX8-NEXT:    v_lshrrev_b32_e32 v5, 16, v0
315; GFX8-NEXT:    v_add_u16_e32 v6, v5, v4
316; GFX8-NEXT:    v_mov_b32_e32 v7, 0xffff8000
317; GFX8-NEXT:    v_mov_b32_e32 v8, 0x7fff
318; GFX8-NEXT:    v_cmp_gt_i16_e32 vcc, 0, v6
319; GFX8-NEXT:    v_cndmask_b32_e32 v9, v7, v8, vcc
320; GFX8-NEXT:    v_cmp_lt_i16_e32 vcc, v6, v5
321; GFX8-NEXT:    v_cmp_gt_i16_e64 s[4:5], 0, v4
322; GFX8-NEXT:    s_xor_b64 vcc, s[4:5], vcc
323; GFX8-NEXT:    v_cndmask_b32_e32 v4, v6, v9, vcc
324; GFX8-NEXT:    v_cmp_gt_i16_e32 vcc, 0, v2
325; GFX8-NEXT:    v_add_u16_e32 v2, v0, v2
326; GFX8-NEXT:    v_cmp_lt_i16_e64 s[4:5], v2, v0
327; GFX8-NEXT:    v_cmp_gt_i16_e64 s[6:7], 0, v2
328; GFX8-NEXT:    v_cndmask_b32_e64 v0, v7, v8, s[6:7]
329; GFX8-NEXT:    s_xor_b64 vcc, vcc, s[4:5]
330; GFX8-NEXT:    v_cndmask_b32_e32 v0, v2, v0, vcc
331; GFX8-NEXT:    v_lshlrev_b32_e32 v4, 16, v4
332; GFX8-NEXT:    v_or_b32_sdwa v0, v0, v4 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
333; GFX8-NEXT:    v_lshrrev_b32_e32 v2, 16, v3
334; GFX8-NEXT:    v_lshrrev_b32_e32 v4, 16, v1
335; GFX8-NEXT:    v_add_u16_e32 v5, v4, v2
336; GFX8-NEXT:    v_cmp_gt_i16_e32 vcc, 0, v5
337; GFX8-NEXT:    v_cndmask_b32_e32 v6, v7, v8, vcc
338; GFX8-NEXT:    v_cmp_lt_i16_e32 vcc, v5, v4
339; GFX8-NEXT:    v_cmp_gt_i16_e64 s[4:5], 0, v2
340; GFX8-NEXT:    s_xor_b64 vcc, s[4:5], vcc
341; GFX8-NEXT:    v_cndmask_b32_e32 v2, v5, v6, vcc
342; GFX8-NEXT:    v_cmp_gt_i16_e32 vcc, 0, v3
343; GFX8-NEXT:    v_add_u16_e32 v3, v1, v3
344; GFX8-NEXT:    v_cmp_lt_i16_e64 s[4:5], v3, v1
345; GFX8-NEXT:    v_cmp_gt_i16_e64 s[6:7], 0, v3
346; GFX8-NEXT:    v_cndmask_b32_e64 v1, v7, v8, s[6:7]
347; GFX8-NEXT:    s_xor_b64 vcc, vcc, s[4:5]
348; GFX8-NEXT:    v_lshlrev_b32_e32 v2, 16, v2
349; GFX8-NEXT:    v_cndmask_b32_e32 v1, v3, v1, vcc
350; GFX8-NEXT:    v_or_b32_sdwa v1, v1, v2 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
351; GFX8-NEXT:    s_setpc_b64 s[30:31]
352;
353; GFX9-LABEL: v_saddsat_v4i16:
354; GFX9:       ; %bb.0:
355; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
356; GFX9-NEXT:    v_pk_add_i16 v0, v0, v2 clamp
357; GFX9-NEXT:    v_pk_add_i16 v1, v1, v3 clamp
358; GFX9-NEXT:    s_setpc_b64 s[30:31]
359;
360; GFX10-LABEL: v_saddsat_v4i16:
361; GFX10:       ; %bb.0:
362; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
363; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
364; GFX10-NEXT:    v_pk_add_i16 v0, v0, v2 clamp
365; GFX10-NEXT:    v_pk_add_i16 v1, v1, v3 clamp
366; GFX10-NEXT:    s_setpc_b64 s[30:31]
367  %result = call <4 x i16> @llvm.sadd.sat.v4i16(<4 x i16> %lhs, <4 x i16> %rhs)
368  %cast = bitcast <4 x i16> %result to <2 x float>
369  ret <2 x float> %cast
370}
371
372define <2 x i32> @v_saddsat_v2i32(<2 x i32> %lhs, <2 x i32> %rhs) {
373; GFX6-LABEL: v_saddsat_v2i32:
374; GFX6:       ; %bb.0:
375; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
376; GFX6-NEXT:    v_cmp_gt_i32_e32 vcc, 0, v2
377; GFX6-NEXT:    v_add_i32_e64 v2, s[4:5], v0, v2
378; GFX6-NEXT:    v_cmp_lt_i32_e64 s[4:5], v2, v0
379; GFX6-NEXT:    v_bfrev_b32_e32 v4, 1
380; GFX6-NEXT:    v_bfrev_b32_e32 v5, -2
381; GFX6-NEXT:    v_cmp_gt_i32_e64 s[6:7], 0, v2
382; GFX6-NEXT:    v_cndmask_b32_e64 v0, v4, v5, s[6:7]
383; GFX6-NEXT:    s_xor_b64 vcc, vcc, s[4:5]
384; GFX6-NEXT:    v_cndmask_b32_e32 v0, v2, v0, vcc
385; GFX6-NEXT:    v_add_i32_e64 v2, s[4:5], v1, v3
386; GFX6-NEXT:    v_cmp_gt_i32_e32 vcc, 0, v3
387; GFX6-NEXT:    v_cmp_lt_i32_e64 s[4:5], v2, v1
388; GFX6-NEXT:    v_cmp_gt_i32_e64 s[6:7], 0, v2
389; GFX6-NEXT:    v_cndmask_b32_e64 v1, v4, v5, s[6:7]
390; GFX6-NEXT:    s_xor_b64 vcc, vcc, s[4:5]
391; GFX6-NEXT:    v_cndmask_b32_e32 v1, v2, v1, vcc
392; GFX6-NEXT:    s_setpc_b64 s[30:31]
393;
394; GFX8-LABEL: v_saddsat_v2i32:
395; GFX8:       ; %bb.0:
396; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
397; GFX8-NEXT:    v_cmp_gt_i32_e32 vcc, 0, v2
398; GFX8-NEXT:    v_add_u32_e64 v2, s[4:5], v0, v2
399; GFX8-NEXT:    v_cmp_lt_i32_e64 s[4:5], v2, v0
400; GFX8-NEXT:    v_bfrev_b32_e32 v4, 1
401; GFX8-NEXT:    v_bfrev_b32_e32 v5, -2
402; GFX8-NEXT:    v_cmp_gt_i32_e64 s[6:7], 0, v2
403; GFX8-NEXT:    v_cndmask_b32_e64 v0, v4, v5, s[6:7]
404; GFX8-NEXT:    s_xor_b64 vcc, vcc, s[4:5]
405; GFX8-NEXT:    v_cndmask_b32_e32 v0, v2, v0, vcc
406; GFX8-NEXT:    v_add_u32_e64 v2, s[4:5], v1, v3
407; GFX8-NEXT:    v_cmp_gt_i32_e32 vcc, 0, v3
408; GFX8-NEXT:    v_cmp_lt_i32_e64 s[4:5], v2, v1
409; GFX8-NEXT:    v_cmp_gt_i32_e64 s[6:7], 0, v2
410; GFX8-NEXT:    v_cndmask_b32_e64 v1, v4, v5, s[6:7]
411; GFX8-NEXT:    s_xor_b64 vcc, vcc, s[4:5]
412; GFX8-NEXT:    v_cndmask_b32_e32 v1, v2, v1, vcc
413; GFX8-NEXT:    s_setpc_b64 s[30:31]
414;
415; GFX9-LABEL: v_saddsat_v2i32:
416; GFX9:       ; %bb.0:
417; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
418; GFX9-NEXT:    v_add_i32 v0, v0, v2 clamp
419; GFX9-NEXT:    v_add_i32 v1, v1, v3 clamp
420; GFX9-NEXT:    s_setpc_b64 s[30:31]
421;
422; GFX10-LABEL: v_saddsat_v2i32:
423; GFX10:       ; %bb.0:
424; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
425; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
426; GFX10-NEXT:    v_add_nc_i32 v0, v0, v2 clamp
427; GFX10-NEXT:    v_add_nc_i32 v1, v1, v3 clamp
428; GFX10-NEXT:    s_setpc_b64 s[30:31]
429  %result = call <2 x i32> @llvm.sadd.sat.v2i32(<2 x i32> %lhs, <2 x i32> %rhs)
430  ret <2 x i32> %result
431}
432
433define i64 @v_saddsat_i64(i64 %lhs, i64 %rhs) {
434; GFX6-LABEL: v_saddsat_i64:
435; GFX6:       ; %bb.0:
436; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
437; GFX6-NEXT:    v_add_i32_e32 v4, vcc, v0, v2
438; GFX6-NEXT:    v_addc_u32_e32 v5, vcc, v1, v3, vcc
439; GFX6-NEXT:    v_cmp_lt_i64_e32 vcc, v[4:5], v[0:1]
440; GFX6-NEXT:    v_cmp_gt_i64_e64 s[4:5], 0, v[2:3]
441; GFX6-NEXT:    v_bfrev_b32_e32 v1, 1
442; GFX6-NEXT:    s_xor_b64 vcc, s[4:5], vcc
443; GFX6-NEXT:    v_cmp_gt_i64_e64 s[4:5], 0, v[4:5]
444; GFX6-NEXT:    v_bfrev_b32_e32 v2, -2
445; GFX6-NEXT:    v_ashrrev_i32_e32 v0, 31, v5
446; GFX6-NEXT:    v_cndmask_b32_e64 v1, v1, v2, s[4:5]
447; GFX6-NEXT:    v_cndmask_b32_e32 v0, v4, v0, vcc
448; GFX6-NEXT:    v_cndmask_b32_e32 v1, v5, v1, vcc
449; GFX6-NEXT:    s_setpc_b64 s[30:31]
450;
451; GFX8-LABEL: v_saddsat_i64:
452; GFX8:       ; %bb.0:
453; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
454; GFX8-NEXT:    v_add_u32_e32 v4, vcc, v0, v2
455; GFX8-NEXT:    v_addc_u32_e32 v5, vcc, v1, v3, vcc
456; GFX8-NEXT:    v_cmp_lt_i64_e32 vcc, v[4:5], v[0:1]
457; GFX8-NEXT:    v_cmp_gt_i64_e64 s[4:5], 0, v[2:3]
458; GFX8-NEXT:    v_bfrev_b32_e32 v1, 1
459; GFX8-NEXT:    s_xor_b64 vcc, s[4:5], vcc
460; GFX8-NEXT:    v_cmp_gt_i64_e64 s[4:5], 0, v[4:5]
461; GFX8-NEXT:    v_bfrev_b32_e32 v2, -2
462; GFX8-NEXT:    v_ashrrev_i32_e32 v0, 31, v5
463; GFX8-NEXT:    v_cndmask_b32_e64 v1, v1, v2, s[4:5]
464; GFX8-NEXT:    v_cndmask_b32_e32 v0, v4, v0, vcc
465; GFX8-NEXT:    v_cndmask_b32_e32 v1, v5, v1, vcc
466; GFX8-NEXT:    s_setpc_b64 s[30:31]
467;
468; GFX9-LABEL: v_saddsat_i64:
469; GFX9:       ; %bb.0:
470; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
471; GFX9-NEXT:    v_add_co_u32_e32 v4, vcc, v0, v2
472; GFX9-NEXT:    v_addc_co_u32_e32 v5, vcc, v1, v3, vcc
473; GFX9-NEXT:    v_cmp_lt_i64_e32 vcc, v[4:5], v[0:1]
474; GFX9-NEXT:    v_cmp_gt_i64_e64 s[4:5], 0, v[2:3]
475; GFX9-NEXT:    v_bfrev_b32_e32 v1, 1
476; GFX9-NEXT:    s_xor_b64 vcc, s[4:5], vcc
477; GFX9-NEXT:    v_cmp_gt_i64_e64 s[4:5], 0, v[4:5]
478; GFX9-NEXT:    v_bfrev_b32_e32 v2, -2
479; GFX9-NEXT:    v_ashrrev_i32_e32 v0, 31, v5
480; GFX9-NEXT:    v_cndmask_b32_e64 v1, v1, v2, s[4:5]
481; GFX9-NEXT:    v_cndmask_b32_e32 v0, v4, v0, vcc
482; GFX9-NEXT:    v_cndmask_b32_e32 v1, v5, v1, vcc
483; GFX9-NEXT:    s_setpc_b64 s[30:31]
484;
485; GFX10-LABEL: v_saddsat_i64:
486; GFX10:       ; %bb.0:
487; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
488; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
489; GFX10-NEXT:    v_add_co_u32 v4, vcc_lo, v0, v2
490; GFX10-NEXT:    v_bfrev_b32_e32 v6, -2
491; GFX10-NEXT:    v_add_co_ci_u32_e32 v5, vcc_lo, v1, v3, vcc_lo
492; GFX10-NEXT:    v_cmp_gt_i64_e64 s4, 0, v[2:3]
493; GFX10-NEXT:    v_cmp_gt_i64_e64 s5, 0, v[4:5]
494; GFX10-NEXT:    v_cmp_lt_i64_e32 vcc_lo, v[4:5], v[0:1]
495; GFX10-NEXT:    v_ashrrev_i32_e32 v0, 31, v5
496; GFX10-NEXT:    v_cndmask_b32_e64 v1, 0x80000000, v6, s5
497; GFX10-NEXT:    s_xor_b32 vcc_lo, s4, vcc_lo
498; GFX10-NEXT:    v_cndmask_b32_e32 v0, v4, v0, vcc_lo
499; GFX10-NEXT:    v_cndmask_b32_e32 v1, v5, v1, vcc_lo
500; GFX10-NEXT:    s_setpc_b64 s[30:31]
501  %result = call i64 @llvm.sadd.sat.i64(i64 %lhs, i64 %rhs)
502  ret i64 %result
503}
504
505declare i8 @llvm.sadd.sat.i8(i8, i8) #0
506declare i16 @llvm.sadd.sat.i16(i16, i16) #0
507declare <2 x i16> @llvm.sadd.sat.v2i16(<2 x i16>, <2 x i16>) #0
508declare <3 x i16> @llvm.sadd.sat.v3i16(<3 x i16>, <3 x i16>) #0
509declare <4 x i16> @llvm.sadd.sat.v4i16(<4 x i16>, <4 x i16>) #0
510declare i32 @llvm.sadd.sat.i32(i32, i32) #0
511declare <2 x i32> @llvm.sadd.sat.v2i32(<2 x i32>, <2 x i32>) #0
512declare i64 @llvm.sadd.sat.i64(i64, i64) #0
513