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