1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -global-isel -march=amdgcn -mcpu=tahiti < %s | FileCheck -check-prefix=GFX6 %s
3; RUN: llc -global-isel -march=amdgcn -mcpu=hawaii < %s | FileCheck -check-prefix=GFX7 %s
4; RUN: llc -global-isel -march=amdgcn -mcpu=fiji < %s | FileCheck -check-prefix=GFX8 %s
5; RUN: llc -global-isel -march=amdgcn -mcpu=gfx900 < %s | FileCheck -check-prefix=GFX9 %s
6; RUN: llc -global-isel -march=amdgcn -mcpu=gfx1010 < %s | FileCheck -check-prefix=GFX10 %s
7
8define float @v_roundeven_f32(float %x) {
9; GFX6-LABEL: v_roundeven_f32:
10; GFX6:       ; %bb.0:
11; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
12; GFX6-NEXT:    v_rndne_f32_e32 v0, v0
13; GFX6-NEXT:    s_setpc_b64 s[30:31]
14;
15; GFX7-LABEL: v_roundeven_f32:
16; GFX7:       ; %bb.0:
17; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
18; GFX7-NEXT:    v_rndne_f32_e32 v0, v0
19; GFX7-NEXT:    s_setpc_b64 s[30:31]
20;
21; GFX8-LABEL: v_roundeven_f32:
22; GFX8:       ; %bb.0:
23; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
24; GFX8-NEXT:    v_rndne_f32_e32 v0, v0
25; GFX8-NEXT:    s_setpc_b64 s[30:31]
26;
27; GFX9-LABEL: v_roundeven_f32:
28; GFX9:       ; %bb.0:
29; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
30; GFX9-NEXT:    v_rndne_f32_e32 v0, v0
31; GFX9-NEXT:    s_setpc_b64 s[30:31]
32;
33; GFX10-LABEL: v_roundeven_f32:
34; GFX10:       ; %bb.0:
35; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
36; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
37; GFX10-NEXT:    v_rndne_f32_e32 v0, v0
38; GFX10-NEXT:    s_setpc_b64 s[30:31]
39  %roundeven = call float @llvm.roundeven.f32(float %x)
40  ret float %roundeven
41}
42
43define <2 x float> @v_roundeven_v2f32(<2 x float> %x) {
44; GFX6-LABEL: v_roundeven_v2f32:
45; GFX6:       ; %bb.0:
46; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
47; GFX6-NEXT:    v_rndne_f32_e32 v0, v0
48; GFX6-NEXT:    v_rndne_f32_e32 v1, v1
49; GFX6-NEXT:    s_setpc_b64 s[30:31]
50;
51; GFX7-LABEL: v_roundeven_v2f32:
52; GFX7:       ; %bb.0:
53; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
54; GFX7-NEXT:    v_rndne_f32_e32 v0, v0
55; GFX7-NEXT:    v_rndne_f32_e32 v1, v1
56; GFX7-NEXT:    s_setpc_b64 s[30:31]
57;
58; GFX8-LABEL: v_roundeven_v2f32:
59; GFX8:       ; %bb.0:
60; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
61; GFX8-NEXT:    v_rndne_f32_e32 v0, v0
62; GFX8-NEXT:    v_rndne_f32_e32 v1, v1
63; GFX8-NEXT:    s_setpc_b64 s[30:31]
64;
65; GFX9-LABEL: v_roundeven_v2f32:
66; GFX9:       ; %bb.0:
67; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
68; GFX9-NEXT:    v_rndne_f32_e32 v0, v0
69; GFX9-NEXT:    v_rndne_f32_e32 v1, v1
70; GFX9-NEXT:    s_setpc_b64 s[30:31]
71;
72; GFX10-LABEL: v_roundeven_v2f32:
73; GFX10:       ; %bb.0:
74; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
75; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
76; GFX10-NEXT:    v_rndne_f32_e32 v0, v0
77; GFX10-NEXT:    v_rndne_f32_e32 v1, v1
78; GFX10-NEXT:    s_setpc_b64 s[30:31]
79  %roundeven = call <2 x float> @llvm.roundeven.v2f32(<2 x float> %x)
80  ret <2 x float> %roundeven
81}
82
83define <3 x float> @v_roundeven_v3f32(<3 x float> %x) {
84; GFX6-LABEL: v_roundeven_v3f32:
85; GFX6:       ; %bb.0:
86; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
87; GFX6-NEXT:    v_rndne_f32_e32 v0, v0
88; GFX6-NEXT:    v_rndne_f32_e32 v1, v1
89; GFX6-NEXT:    v_rndne_f32_e32 v2, v2
90; GFX6-NEXT:    s_setpc_b64 s[30:31]
91;
92; GFX7-LABEL: v_roundeven_v3f32:
93; GFX7:       ; %bb.0:
94; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
95; GFX7-NEXT:    v_rndne_f32_e32 v0, v0
96; GFX7-NEXT:    v_rndne_f32_e32 v1, v1
97; GFX7-NEXT:    v_rndne_f32_e32 v2, v2
98; GFX7-NEXT:    s_setpc_b64 s[30:31]
99;
100; GFX8-LABEL: v_roundeven_v3f32:
101; GFX8:       ; %bb.0:
102; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
103; GFX8-NEXT:    v_rndne_f32_e32 v0, v0
104; GFX8-NEXT:    v_rndne_f32_e32 v1, v1
105; GFX8-NEXT:    v_rndne_f32_e32 v2, v2
106; GFX8-NEXT:    s_setpc_b64 s[30:31]
107;
108; GFX9-LABEL: v_roundeven_v3f32:
109; GFX9:       ; %bb.0:
110; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
111; GFX9-NEXT:    v_rndne_f32_e32 v0, v0
112; GFX9-NEXT:    v_rndne_f32_e32 v1, v1
113; GFX9-NEXT:    v_rndne_f32_e32 v2, v2
114; GFX9-NEXT:    s_setpc_b64 s[30:31]
115;
116; GFX10-LABEL: v_roundeven_v3f32:
117; GFX10:       ; %bb.0:
118; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
119; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
120; GFX10-NEXT:    v_rndne_f32_e32 v0, v0
121; GFX10-NEXT:    v_rndne_f32_e32 v1, v1
122; GFX10-NEXT:    v_rndne_f32_e32 v2, v2
123; GFX10-NEXT:    s_setpc_b64 s[30:31]
124  %roundeven = call <3 x float> @llvm.roundeven.v3f32(<3 x float> %x)
125  ret <3 x float> %roundeven
126}
127
128define <4 x float> @v_roundeven_v4f32(<4 x float> %x) {
129; GFX6-LABEL: v_roundeven_v4f32:
130; GFX6:       ; %bb.0:
131; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
132; GFX6-NEXT:    v_rndne_f32_e32 v0, v0
133; GFX6-NEXT:    v_rndne_f32_e32 v1, v1
134; GFX6-NEXT:    v_rndne_f32_e32 v2, v2
135; GFX6-NEXT:    v_rndne_f32_e32 v3, v3
136; GFX6-NEXT:    s_setpc_b64 s[30:31]
137;
138; GFX7-LABEL: v_roundeven_v4f32:
139; GFX7:       ; %bb.0:
140; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
141; GFX7-NEXT:    v_rndne_f32_e32 v0, v0
142; GFX7-NEXT:    v_rndne_f32_e32 v1, v1
143; GFX7-NEXT:    v_rndne_f32_e32 v2, v2
144; GFX7-NEXT:    v_rndne_f32_e32 v3, v3
145; GFX7-NEXT:    s_setpc_b64 s[30:31]
146;
147; GFX8-LABEL: v_roundeven_v4f32:
148; GFX8:       ; %bb.0:
149; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
150; GFX8-NEXT:    v_rndne_f32_e32 v0, v0
151; GFX8-NEXT:    v_rndne_f32_e32 v1, v1
152; GFX8-NEXT:    v_rndne_f32_e32 v2, v2
153; GFX8-NEXT:    v_rndne_f32_e32 v3, v3
154; GFX8-NEXT:    s_setpc_b64 s[30:31]
155;
156; GFX9-LABEL: v_roundeven_v4f32:
157; GFX9:       ; %bb.0:
158; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
159; GFX9-NEXT:    v_rndne_f32_e32 v0, v0
160; GFX9-NEXT:    v_rndne_f32_e32 v1, v1
161; GFX9-NEXT:    v_rndne_f32_e32 v2, v2
162; GFX9-NEXT:    v_rndne_f32_e32 v3, v3
163; GFX9-NEXT:    s_setpc_b64 s[30:31]
164;
165; GFX10-LABEL: v_roundeven_v4f32:
166; GFX10:       ; %bb.0:
167; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
168; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
169; GFX10-NEXT:    v_rndne_f32_e32 v0, v0
170; GFX10-NEXT:    v_rndne_f32_e32 v1, v1
171; GFX10-NEXT:    v_rndne_f32_e32 v2, v2
172; GFX10-NEXT:    v_rndne_f32_e32 v3, v3
173; GFX10-NEXT:    s_setpc_b64 s[30:31]
174  %roundeven = call <4 x float> @llvm.roundeven.v4f32(<4 x float> %x)
175  ret <4 x float> %roundeven
176}
177
178define half @v_roundeven_f16(half %x) {
179; GFX6-LABEL: v_roundeven_f16:
180; GFX6:       ; %bb.0:
181; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
182; GFX6-NEXT:    v_cvt_f32_f16_e32 v0, v0
183; GFX6-NEXT:    v_rndne_f32_e32 v0, v0
184; GFX6-NEXT:    v_cvt_f16_f32_e32 v0, v0
185; GFX6-NEXT:    s_setpc_b64 s[30:31]
186;
187; GFX7-LABEL: v_roundeven_f16:
188; GFX7:       ; %bb.0:
189; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
190; GFX7-NEXT:    v_cvt_f32_f16_e32 v0, v0
191; GFX7-NEXT:    v_rndne_f32_e32 v0, v0
192; GFX7-NEXT:    v_cvt_f16_f32_e32 v0, v0
193; GFX7-NEXT:    s_setpc_b64 s[30:31]
194;
195; GFX8-LABEL: v_roundeven_f16:
196; GFX8:       ; %bb.0:
197; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
198; GFX8-NEXT:    v_rndne_f16_e32 v0, v0
199; GFX8-NEXT:    s_setpc_b64 s[30:31]
200;
201; GFX9-LABEL: v_roundeven_f16:
202; GFX9:       ; %bb.0:
203; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
204; GFX9-NEXT:    v_rndne_f16_e32 v0, v0
205; GFX9-NEXT:    s_setpc_b64 s[30:31]
206;
207; GFX10-LABEL: v_roundeven_f16:
208; GFX10:       ; %bb.0:
209; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
210; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
211; GFX10-NEXT:    v_rndne_f16_e32 v0, v0
212; GFX10-NEXT:    s_setpc_b64 s[30:31]
213  %roundeven = call half @llvm.roundeven.f16(half %x)
214  ret half %roundeven
215}
216
217define <2 x half> @v_roundeven_v2f16(<2 x half> %x) {
218; GFX6-LABEL: v_roundeven_v2f16:
219; GFX6:       ; %bb.0:
220; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
221; GFX6-NEXT:    v_cvt_f32_f16_e32 v1, v0
222; GFX6-NEXT:    v_lshrrev_b32_e32 v0, 16, v0
223; GFX6-NEXT:    v_cvt_f32_f16_e32 v0, v0
224; GFX6-NEXT:    v_rndne_f32_e32 v1, v1
225; GFX6-NEXT:    v_cvt_f16_f32_e32 v1, v1
226; GFX6-NEXT:    v_rndne_f32_e32 v0, v0
227; GFX6-NEXT:    v_cvt_f16_f32_e32 v0, v0
228; GFX6-NEXT:    v_bfe_u32 v1, v1, 0, 16
229; GFX6-NEXT:    v_bfe_u32 v0, v0, 0, 16
230; GFX6-NEXT:    v_lshlrev_b32_e32 v0, 16, v0
231; GFX6-NEXT:    v_or_b32_e32 v0, v1, v0
232; GFX6-NEXT:    s_setpc_b64 s[30:31]
233;
234; GFX7-LABEL: v_roundeven_v2f16:
235; GFX7:       ; %bb.0:
236; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
237; GFX7-NEXT:    v_cvt_f32_f16_e32 v1, v0
238; GFX7-NEXT:    v_lshrrev_b32_e32 v0, 16, v0
239; GFX7-NEXT:    v_cvt_f32_f16_e32 v0, v0
240; GFX7-NEXT:    v_rndne_f32_e32 v1, v1
241; GFX7-NEXT:    v_cvt_f16_f32_e32 v1, v1
242; GFX7-NEXT:    v_rndne_f32_e32 v0, v0
243; GFX7-NEXT:    v_cvt_f16_f32_e32 v0, v0
244; GFX7-NEXT:    v_bfe_u32 v1, v1, 0, 16
245; GFX7-NEXT:    v_bfe_u32 v0, v0, 0, 16
246; GFX7-NEXT:    v_lshlrev_b32_e32 v0, 16, v0
247; GFX7-NEXT:    v_or_b32_e32 v0, v1, v0
248; GFX7-NEXT:    s_setpc_b64 s[30:31]
249;
250; GFX8-LABEL: v_roundeven_v2f16:
251; GFX8:       ; %bb.0:
252; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
253; GFX8-NEXT:    v_rndne_f16_e32 v1, v0
254; GFX8-NEXT:    v_rndne_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
255; GFX8-NEXT:    v_mov_b32_e32 v2, 16
256; GFX8-NEXT:    v_lshlrev_b32_sdwa v0, v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
257; GFX8-NEXT:    v_or_b32_sdwa v0, v1, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
258; GFX8-NEXT:    s_setpc_b64 s[30:31]
259;
260; GFX9-LABEL: v_roundeven_v2f16:
261; GFX9:       ; %bb.0:
262; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
263; GFX9-NEXT:    v_rndne_f16_e32 v1, v0
264; GFX9-NEXT:    v_rndne_f16_sdwa v0, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1
265; GFX9-NEXT:    v_mov_b32_e32 v2, 0xffff
266; GFX9-NEXT:    v_and_or_b32 v0, v1, v2, v0
267; GFX9-NEXT:    s_setpc_b64 s[30:31]
268;
269; GFX10-LABEL: v_roundeven_v2f16:
270; GFX10:       ; %bb.0:
271; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
272; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
273; GFX10-NEXT:    v_rndne_f16_e32 v1, v0
274; GFX10-NEXT:    v_rndne_f16_sdwa v0, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1
275; GFX10-NEXT:    v_and_or_b32 v0, 0xffff, v1, v0
276; GFX10-NEXT:    s_setpc_b64 s[30:31]
277  %roundeven = call <2 x half> @llvm.roundeven.v2f16(<2 x half> %x)
278  ret <2 x half> %roundeven
279}
280
281define <2 x half> @v_roundeven_v2f16_fneg(<2 x half> %x) {
282; GFX6-LABEL: v_roundeven_v2f16_fneg:
283; GFX6:       ; %bb.0:
284; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
285; GFX6-NEXT:    v_xor_b32_e32 v0, 0x80008000, v0
286; GFX6-NEXT:    v_cvt_f32_f16_e32 v1, v0
287; GFX6-NEXT:    v_lshrrev_b32_e32 v0, 16, v0
288; GFX6-NEXT:    v_cvt_f32_f16_e32 v0, v0
289; GFX6-NEXT:    v_rndne_f32_e32 v1, v1
290; GFX6-NEXT:    v_cvt_f16_f32_e32 v1, v1
291; GFX6-NEXT:    v_rndne_f32_e32 v0, v0
292; GFX6-NEXT:    v_cvt_f16_f32_e32 v0, v0
293; GFX6-NEXT:    v_bfe_u32 v1, v1, 0, 16
294; GFX6-NEXT:    v_bfe_u32 v0, v0, 0, 16
295; GFX6-NEXT:    v_lshlrev_b32_e32 v0, 16, v0
296; GFX6-NEXT:    v_or_b32_e32 v0, v1, v0
297; GFX6-NEXT:    s_setpc_b64 s[30:31]
298;
299; GFX7-LABEL: v_roundeven_v2f16_fneg:
300; GFX7:       ; %bb.0:
301; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
302; GFX7-NEXT:    v_xor_b32_e32 v0, 0x80008000, v0
303; GFX7-NEXT:    v_cvt_f32_f16_e32 v1, v0
304; GFX7-NEXT:    v_lshrrev_b32_e32 v0, 16, v0
305; GFX7-NEXT:    v_cvt_f32_f16_e32 v0, v0
306; GFX7-NEXT:    v_rndne_f32_e32 v1, v1
307; GFX7-NEXT:    v_cvt_f16_f32_e32 v1, v1
308; GFX7-NEXT:    v_rndne_f32_e32 v0, v0
309; GFX7-NEXT:    v_cvt_f16_f32_e32 v0, v0
310; GFX7-NEXT:    v_bfe_u32 v1, v1, 0, 16
311; GFX7-NEXT:    v_bfe_u32 v0, v0, 0, 16
312; GFX7-NEXT:    v_lshlrev_b32_e32 v0, 16, v0
313; GFX7-NEXT:    v_or_b32_e32 v0, v1, v0
314; GFX7-NEXT:    s_setpc_b64 s[30:31]
315;
316; GFX8-LABEL: v_roundeven_v2f16_fneg:
317; GFX8:       ; %bb.0:
318; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
319; GFX8-NEXT:    v_xor_b32_e32 v0, 0x80008000, v0
320; GFX8-NEXT:    v_rndne_f16_e32 v1, v0
321; GFX8-NEXT:    v_rndne_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
322; GFX8-NEXT:    v_mov_b32_e32 v2, 16
323; GFX8-NEXT:    v_lshlrev_b32_sdwa v0, v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
324; GFX8-NEXT:    v_or_b32_sdwa v0, v1, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
325; GFX8-NEXT:    s_setpc_b64 s[30:31]
326;
327; GFX9-LABEL: v_roundeven_v2f16_fneg:
328; GFX9:       ; %bb.0:
329; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
330; GFX9-NEXT:    v_xor_b32_e32 v0, 0x80008000, v0
331; GFX9-NEXT:    v_rndne_f16_e32 v1, v0
332; GFX9-NEXT:    v_rndne_f16_sdwa v0, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1
333; GFX9-NEXT:    v_mov_b32_e32 v2, 0xffff
334; GFX9-NEXT:    v_and_or_b32 v0, v1, v2, v0
335; GFX9-NEXT:    s_setpc_b64 s[30:31]
336;
337; GFX10-LABEL: v_roundeven_v2f16_fneg:
338; GFX10:       ; %bb.0:
339; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
340; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
341; GFX10-NEXT:    v_xor_b32_e32 v0, 0x80008000, v0
342; GFX10-NEXT:    v_rndne_f16_e32 v1, v0
343; GFX10-NEXT:    v_rndne_f16_sdwa v0, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1
344; GFX10-NEXT:    v_and_or_b32 v0, 0xffff, v1, v0
345; GFX10-NEXT:    s_setpc_b64 s[30:31]
346  %x.fneg = fneg <2 x half> %x
347  %roundeven = call <2 x half> @llvm.roundeven.v2f16(<2 x half> %x.fneg)
348  ret <2 x half> %roundeven
349}
350
351define <4 x half> @v_roundeven_v4f16(<4 x half> %x) {
352; GFX6-LABEL: v_roundeven_v4f16:
353; GFX6:       ; %bb.0:
354; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
355; GFX6-NEXT:    v_cvt_f32_f16_e32 v0, v0
356; GFX6-NEXT:    v_cvt_f32_f16_e32 v1, v1
357; GFX6-NEXT:    v_cvt_f32_f16_e32 v2, v2
358; GFX6-NEXT:    v_cvt_f32_f16_e32 v3, v3
359; GFX6-NEXT:    v_rndne_f32_e32 v0, v0
360; GFX6-NEXT:    v_rndne_f32_e32 v1, v1
361; GFX6-NEXT:    v_rndne_f32_e32 v2, v2
362; GFX6-NEXT:    v_rndne_f32_e32 v3, v3
363; GFX6-NEXT:    v_cvt_f16_f32_e32 v0, v0
364; GFX6-NEXT:    v_cvt_f16_f32_e32 v1, v1
365; GFX6-NEXT:    v_cvt_f16_f32_e32 v2, v2
366; GFX6-NEXT:    v_cvt_f16_f32_e32 v3, v3
367; GFX6-NEXT:    s_setpc_b64 s[30:31]
368;
369; GFX7-LABEL: v_roundeven_v4f16:
370; GFX7:       ; %bb.0:
371; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
372; GFX7-NEXT:    v_cvt_f32_f16_e32 v0, v0
373; GFX7-NEXT:    v_cvt_f32_f16_e32 v1, v1
374; GFX7-NEXT:    v_cvt_f32_f16_e32 v2, v2
375; GFX7-NEXT:    v_cvt_f32_f16_e32 v3, v3
376; GFX7-NEXT:    v_rndne_f32_e32 v0, v0
377; GFX7-NEXT:    v_rndne_f32_e32 v1, v1
378; GFX7-NEXT:    v_rndne_f32_e32 v2, v2
379; GFX7-NEXT:    v_rndne_f32_e32 v3, v3
380; GFX7-NEXT:    v_cvt_f16_f32_e32 v0, v0
381; GFX7-NEXT:    v_cvt_f16_f32_e32 v1, v1
382; GFX7-NEXT:    v_cvt_f16_f32_e32 v2, v2
383; GFX7-NEXT:    v_cvt_f16_f32_e32 v3, v3
384; GFX7-NEXT:    s_setpc_b64 s[30:31]
385;
386; GFX8-LABEL: v_roundeven_v4f16:
387; GFX8:       ; %bb.0:
388; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
389; GFX8-NEXT:    v_rndne_f16_e32 v2, v0
390; GFX8-NEXT:    v_rndne_f16_e32 v3, v1
391; GFX8-NEXT:    v_rndne_f16_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
392; GFX8-NEXT:    v_mov_b32_e32 v4, 16
393; GFX8-NEXT:    v_rndne_f16_sdwa v1, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1
394; GFX8-NEXT:    v_lshlrev_b32_sdwa v0, v4, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
395; GFX8-NEXT:    v_lshlrev_b32_sdwa v1, v4, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:WORD_0
396; GFX8-NEXT:    v_or_b32_sdwa v0, v2, v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
397; GFX8-NEXT:    v_or_b32_sdwa v1, v3, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
398; GFX8-NEXT:    s_setpc_b64 s[30:31]
399;
400; GFX9-LABEL: v_roundeven_v4f16:
401; GFX9:       ; %bb.0:
402; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
403; GFX9-NEXT:    v_rndne_f16_e32 v2, v0
404; GFX9-NEXT:    v_rndne_f16_e32 v3, v1
405; GFX9-NEXT:    v_rndne_f16_sdwa v0, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1
406; GFX9-NEXT:    v_mov_b32_e32 v4, 0xffff
407; GFX9-NEXT:    v_rndne_f16_sdwa v1, v1 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1
408; GFX9-NEXT:    v_and_or_b32 v0, v2, v4, v0
409; GFX9-NEXT:    v_and_or_b32 v1, v3, v4, v1
410; GFX9-NEXT:    s_setpc_b64 s[30:31]
411;
412; GFX10-LABEL: v_roundeven_v4f16:
413; GFX10:       ; %bb.0:
414; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
415; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
416; GFX10-NEXT:    v_rndne_f16_e32 v2, v0
417; GFX10-NEXT:    v_rndne_f16_e32 v3, v1
418; GFX10-NEXT:    v_rndne_f16_sdwa v0, v0 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1
419; GFX10-NEXT:    v_mov_b32_e32 v4, 0xffff
420; GFX10-NEXT:    v_rndne_f16_sdwa v1, v1 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:WORD_1
421; GFX10-NEXT:    v_and_or_b32 v0, v2, v4, v0
422; GFX10-NEXT:    v_and_or_b32 v1, v3, v4, v1
423; GFX10-NEXT:    s_setpc_b64 s[30:31]
424  %roundeven = call <4 x half> @llvm.roundeven.v4f16(<4 x half> %x)
425  ret <4 x half> %roundeven
426}
427
428
429define float @v_roundeven_f32_fabs(float %x) {
430; GFX6-LABEL: v_roundeven_f32_fabs:
431; GFX6:       ; %bb.0:
432; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
433; GFX6-NEXT:    v_rndne_f32_e64 v0, |v0|
434; GFX6-NEXT:    s_setpc_b64 s[30:31]
435;
436; GFX7-LABEL: v_roundeven_f32_fabs:
437; GFX7:       ; %bb.0:
438; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
439; GFX7-NEXT:    v_rndne_f32_e64 v0, |v0|
440; GFX7-NEXT:    s_setpc_b64 s[30:31]
441;
442; GFX8-LABEL: v_roundeven_f32_fabs:
443; GFX8:       ; %bb.0:
444; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
445; GFX8-NEXT:    v_rndne_f32_e64 v0, |v0|
446; GFX8-NEXT:    s_setpc_b64 s[30:31]
447;
448; GFX9-LABEL: v_roundeven_f32_fabs:
449; GFX9:       ; %bb.0:
450; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
451; GFX9-NEXT:    v_rndne_f32_e64 v0, |v0|
452; GFX9-NEXT:    s_setpc_b64 s[30:31]
453;
454; GFX10-LABEL: v_roundeven_f32_fabs:
455; GFX10:       ; %bb.0:
456; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
457; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
458; GFX10-NEXT:    v_rndne_f32_e64 v0, |v0|
459; GFX10-NEXT:    s_setpc_b64 s[30:31]
460  %fabs.x = call float @llvm.fabs.f32(float %x)
461  %roundeven = call float @llvm.roundeven.f32(float %fabs.x)
462  ret float %roundeven
463}
464
465define amdgpu_ps float @s_roundeven_f32(float inreg %x) {
466; GFX6-LABEL: s_roundeven_f32:
467; GFX6:       ; %bb.0:
468; GFX6-NEXT:    v_rndne_f32_e32 v0, s0
469; GFX6-NEXT:    ; return to shader part epilog
470;
471; GFX7-LABEL: s_roundeven_f32:
472; GFX7:       ; %bb.0:
473; GFX7-NEXT:    v_rndne_f32_e32 v0, s0
474; GFX7-NEXT:    ; return to shader part epilog
475;
476; GFX8-LABEL: s_roundeven_f32:
477; GFX8:       ; %bb.0:
478; GFX8-NEXT:    v_rndne_f32_e32 v0, s0
479; GFX8-NEXT:    ; return to shader part epilog
480;
481; GFX9-LABEL: s_roundeven_f32:
482; GFX9:       ; %bb.0:
483; GFX9-NEXT:    v_rndne_f32_e32 v0, s0
484; GFX9-NEXT:    ; return to shader part epilog
485;
486; GFX10-LABEL: s_roundeven_f32:
487; GFX10:       ; %bb.0:
488; GFX10-NEXT:    v_rndne_f32_e32 v0, s0
489; GFX10-NEXT:    ; return to shader part epilog
490  %roundeven = call float @llvm.roundeven.f32(float %x)
491  ret float %roundeven
492}
493
494define float @v_roundeven_f32_fneg(float %x) {
495; GFX6-LABEL: v_roundeven_f32_fneg:
496; GFX6:       ; %bb.0:
497; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
498; GFX6-NEXT:    v_rndne_f32_e64 v0, -v0
499; GFX6-NEXT:    s_setpc_b64 s[30:31]
500;
501; GFX7-LABEL: v_roundeven_f32_fneg:
502; GFX7:       ; %bb.0:
503; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
504; GFX7-NEXT:    v_rndne_f32_e64 v0, -v0
505; GFX7-NEXT:    s_setpc_b64 s[30:31]
506;
507; GFX8-LABEL: v_roundeven_f32_fneg:
508; GFX8:       ; %bb.0:
509; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
510; GFX8-NEXT:    v_rndne_f32_e64 v0, -v0
511; GFX8-NEXT:    s_setpc_b64 s[30:31]
512;
513; GFX9-LABEL: v_roundeven_f32_fneg:
514; GFX9:       ; %bb.0:
515; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
516; GFX9-NEXT:    v_rndne_f32_e64 v0, -v0
517; GFX9-NEXT:    s_setpc_b64 s[30:31]
518;
519; GFX10-LABEL: v_roundeven_f32_fneg:
520; GFX10:       ; %bb.0:
521; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
522; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
523; GFX10-NEXT:    v_rndne_f32_e64 v0, -v0
524; GFX10-NEXT:    s_setpc_b64 s[30:31]
525  %neg.x = fneg float %x
526  %roundeven = call float @llvm.roundeven.f32(float %neg.x)
527  ret float %roundeven
528}
529
530define double @v_roundeven_f64(double %x) {
531; GFX6-LABEL: v_roundeven_f64:
532; GFX6:       ; %bb.0:
533; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
534; GFX6-NEXT:    v_and_b32_e32 v3, 0x80000000, v1
535; GFX6-NEXT:    v_mov_b32_e32 v2, 0
536; GFX6-NEXT:    v_or_b32_e32 v3, 0x43300000, v3
537; GFX6-NEXT:    v_add_f64 v[4:5], v[0:1], v[2:3]
538; GFX6-NEXT:    s_mov_b32 s4, -1
539; GFX6-NEXT:    s_mov_b32 s5, 0x432fffff
540; GFX6-NEXT:    v_add_f64 v[2:3], v[4:5], -v[2:3]
541; GFX6-NEXT:    v_cmp_gt_f64_e64 vcc, |v[0:1]|, s[4:5]
542; GFX6-NEXT:    v_cndmask_b32_e32 v0, v2, v0, vcc
543; GFX6-NEXT:    v_cndmask_b32_e32 v1, v3, v1, vcc
544; GFX6-NEXT:    s_setpc_b64 s[30:31]
545;
546; GFX7-LABEL: v_roundeven_f64:
547; GFX7:       ; %bb.0:
548; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
549; GFX7-NEXT:    v_rndne_f64_e32 v[0:1], v[0:1]
550; GFX7-NEXT:    s_setpc_b64 s[30:31]
551;
552; GFX8-LABEL: v_roundeven_f64:
553; GFX8:       ; %bb.0:
554; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
555; GFX8-NEXT:    v_rndne_f64_e32 v[0:1], v[0:1]
556; GFX8-NEXT:    s_setpc_b64 s[30:31]
557;
558; GFX9-LABEL: v_roundeven_f64:
559; GFX9:       ; %bb.0:
560; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
561; GFX9-NEXT:    v_rndne_f64_e32 v[0:1], v[0:1]
562; GFX9-NEXT:    s_setpc_b64 s[30:31]
563;
564; GFX10-LABEL: v_roundeven_f64:
565; GFX10:       ; %bb.0:
566; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
567; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
568; GFX10-NEXT:    v_rndne_f64_e32 v[0:1], v[0:1]
569; GFX10-NEXT:    s_setpc_b64 s[30:31]
570  %roundeven = call double @llvm.roundeven.f64(double %x)
571  ret double %roundeven
572}
573
574define double @v_roundeven_f64_fneg(double %x) {
575; GFX6-LABEL: v_roundeven_f64_fneg:
576; GFX6:       ; %bb.0:
577; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
578; GFX6-NEXT:    v_xor_b32_e32 v2, 0x80000000, v1
579; GFX6-NEXT:    v_and_b32_e32 v4, 0x80000000, v2
580; GFX6-NEXT:    v_mov_b32_e32 v3, 0
581; GFX6-NEXT:    v_or_b32_e32 v4, 0x43300000, v4
582; GFX6-NEXT:    v_add_f64 v[5:6], -v[0:1], v[3:4]
583; GFX6-NEXT:    v_mov_b32_e32 v1, v0
584; GFX6-NEXT:    s_mov_b32 s4, -1
585; GFX6-NEXT:    s_mov_b32 s5, 0x432fffff
586; GFX6-NEXT:    v_add_f64 v[3:4], v[5:6], -v[3:4]
587; GFX6-NEXT:    v_cmp_gt_f64_e64 vcc, |v[1:2]|, s[4:5]
588; GFX6-NEXT:    v_cndmask_b32_e32 v0, v3, v0, vcc
589; GFX6-NEXT:    v_cndmask_b32_e32 v1, v4, v2, vcc
590; GFX6-NEXT:    s_setpc_b64 s[30:31]
591;
592; GFX7-LABEL: v_roundeven_f64_fneg:
593; GFX7:       ; %bb.0:
594; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
595; GFX7-NEXT:    v_rndne_f64_e64 v[0:1], -v[0:1]
596; GFX7-NEXT:    s_setpc_b64 s[30:31]
597;
598; GFX8-LABEL: v_roundeven_f64_fneg:
599; GFX8:       ; %bb.0:
600; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
601; GFX8-NEXT:    v_rndne_f64_e64 v[0:1], -v[0:1]
602; GFX8-NEXT:    s_setpc_b64 s[30:31]
603;
604; GFX9-LABEL: v_roundeven_f64_fneg:
605; GFX9:       ; %bb.0:
606; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
607; GFX9-NEXT:    v_rndne_f64_e64 v[0:1], -v[0:1]
608; GFX9-NEXT:    s_setpc_b64 s[30:31]
609;
610; GFX10-LABEL: v_roundeven_f64_fneg:
611; GFX10:       ; %bb.0:
612; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
613; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
614; GFX10-NEXT:    v_rndne_f64_e64 v[0:1], -v[0:1]
615; GFX10-NEXT:    s_setpc_b64 s[30:31]
616  %neg.x = fneg double %x
617  %roundeven = call double @llvm.roundeven.f64(double %neg.x)
618  ret double %roundeven
619}
620
621define <2 x double> @v_roundeven_v2f64(<2 x double> %x) {
622; GFX6-LABEL: v_roundeven_v2f64:
623; GFX6:       ; %bb.0:
624; GFX6-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
625; GFX6-NEXT:    s_brev_b32 s6, 1
626; GFX6-NEXT:    s_mov_b32 s7, 0x43300000
627; GFX6-NEXT:    v_and_b32_e32 v5, s6, v1
628; GFX6-NEXT:    v_mov_b32_e32 v4, 0
629; GFX6-NEXT:    v_or_b32_e32 v5, s7, v5
630; GFX6-NEXT:    v_add_f64 v[6:7], v[0:1], v[4:5]
631; GFX6-NEXT:    s_mov_b32 s4, -1
632; GFX6-NEXT:    s_mov_b32 s5, 0x432fffff
633; GFX6-NEXT:    v_add_f64 v[5:6], v[6:7], -v[4:5]
634; GFX6-NEXT:    v_cmp_gt_f64_e64 vcc, |v[0:1]|, s[4:5]
635; GFX6-NEXT:    v_cndmask_b32_e32 v0, v5, v0, vcc
636; GFX6-NEXT:    v_and_b32_e32 v5, s6, v3
637; GFX6-NEXT:    v_or_b32_e32 v5, s7, v5
638; GFX6-NEXT:    v_add_f64 v[7:8], v[2:3], v[4:5]
639; GFX6-NEXT:    v_cndmask_b32_e32 v1, v6, v1, vcc
640; GFX6-NEXT:    v_add_f64 v[4:5], v[7:8], -v[4:5]
641; GFX6-NEXT:    v_cmp_gt_f64_e64 vcc, |v[2:3]|, s[4:5]
642; GFX6-NEXT:    v_cndmask_b32_e32 v2, v4, v2, vcc
643; GFX6-NEXT:    v_cndmask_b32_e32 v3, v5, v3, vcc
644; GFX6-NEXT:    s_setpc_b64 s[30:31]
645;
646; GFX7-LABEL: v_roundeven_v2f64:
647; GFX7:       ; %bb.0:
648; GFX7-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
649; GFX7-NEXT:    v_rndne_f64_e32 v[0:1], v[0:1]
650; GFX7-NEXT:    v_rndne_f64_e32 v[2:3], v[2:3]
651; GFX7-NEXT:    s_setpc_b64 s[30:31]
652;
653; GFX8-LABEL: v_roundeven_v2f64:
654; GFX8:       ; %bb.0:
655; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
656; GFX8-NEXT:    v_rndne_f64_e32 v[0:1], v[0:1]
657; GFX8-NEXT:    v_rndne_f64_e32 v[2:3], v[2:3]
658; GFX8-NEXT:    s_setpc_b64 s[30:31]
659;
660; GFX9-LABEL: v_roundeven_v2f64:
661; GFX9:       ; %bb.0:
662; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
663; GFX9-NEXT:    v_rndne_f64_e32 v[0:1], v[0:1]
664; GFX9-NEXT:    v_rndne_f64_e32 v[2:3], v[2:3]
665; GFX9-NEXT:    s_setpc_b64 s[30:31]
666;
667; GFX10-LABEL: v_roundeven_v2f64:
668; GFX10:       ; %bb.0:
669; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
670; GFX10-NEXT:    s_waitcnt_vscnt null, 0x0
671; GFX10-NEXT:    v_rndne_f64_e32 v[0:1], v[0:1]
672; GFX10-NEXT:    v_rndne_f64_e32 v[2:3], v[2:3]
673; GFX10-NEXT:    s_setpc_b64 s[30:31]
674  %roundeven = call <2 x double> @llvm.roundeven.v2f64(<2 x double> %x)
675  ret <2 x double> %roundeven
676}
677
678declare half @llvm.roundeven.f16(half) #0
679declare <2 x half> @llvm.roundeven.v2f16(<2 x half>) #0
680declare <4 x half> @llvm.roundeven.v4f16(<4 x half>) #0
681
682declare float @llvm.roundeven.f32(float) #0
683declare <2 x float> @llvm.roundeven.v2f32(<2 x float>) #0
684declare <3 x float> @llvm.roundeven.v3f32(<3 x float>) #0
685declare <4 x float> @llvm.roundeven.v4f32(<4 x float>) #0
686
687declare double @llvm.roundeven.f64(double) #0
688declare <2 x double> @llvm.roundeven.v2f64(<2 x double>) #0
689
690declare half @llvm.fabs.f16(half) #0
691declare float @llvm.fabs.f32(float) #0
692
693attributes #0 = { nounwind readnone speculatable willreturn }
694