1; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=SI %s
2; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs -amdgpu-fast-fdiv < %s | FileCheck -check-prefix=SI %s
3; RUN: llc -march=amdgcn -mcpu=fiji -verify-machineinstrs < %s | FileCheck -check-prefix=I754 %s
4; RUN: llc -march=amdgcn -mcpu=fiji -verify-machineinstrs -enable-unsafe-fp-math < %s | FileCheck -check-prefix=UNSAFE-FP %s
5; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -check-prefix=R600 %s
6
7; These tests check that fdiv is expanded correctly and also test that the
8; scheduler is scheduling the RECIP_IEEE and MUL_IEEE instructions in separate
9; instruction groups.
10
11; These test check that fdiv using unsafe_fp_math, coarse fp div, and IEEE754 fp div.
12
13; FUNC-LABEL: {{^}}fdiv_f32:
14; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Z
15; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Y
16; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[3].X, PS
17; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].W, PS
18
19; UNSAFE-FP: v_rcp_f32
20; UNSAFE-FP: v_mul_f32_e32
21
22; SI-DAG: v_rcp_f32
23; SI-DAG: v_mul_f32
24
25; I754-DAG: v_div_scale_f32
26; I754-DAG: v_rcp_f32
27; I754-DAG: v_fma_f32
28; I754-DAG: v_mul_f32
29; I754-DAG: v_fma_f32
30; I754-DAG: v_div_fixup_f32
31define void @fdiv_f32(float addrspace(1)* %out, float %a, float %b) {
32entry:
33  %0 = fdiv float %a, %b
34  store float %0, float addrspace(1)* %out
35  ret void
36}
37
38; FUNC-LABEL: {{^}}fdiv_f32_fast_math:
39; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Z
40; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Y
41; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[3].X, PS
42; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].W, PS
43
44; UNSAFE-FP: v_rcp_f32
45; UNSAFE-FP: v_mul_f32_e32
46
47; SI-DAG: v_rcp_f32
48; SI-DAG: v_mul_f32
49define void @fdiv_f32_fast_math(float addrspace(1)* %out, float %a, float %b) {
50entry:
51  %0 = fdiv fast float %a, %b
52  store float %0, float addrspace(1)* %out
53  ret void
54}
55
56; FUNC-LABEL: {{^}}fdiv_f32_arcp_math:
57; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Z
58; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Y
59; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[3].X, PS
60; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].W, PS
61
62; UNSAFE-FP: v_rcp_f32
63; UNSAFE-FP: v_mul_f32_e32
64
65; SI-DAG: v_rcp_f32
66; SI-DAG: v_mul_f32
67define void @fdiv_f32_arcp_math(float addrspace(1)* %out, float %a, float %b) {
68entry:
69  %0 = fdiv arcp float %a, %b
70  store float %0, float addrspace(1)* %out
71  ret void
72}
73
74; FUNC-LABEL: {{^}}fdiv_v2f32:
75; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Z
76; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Y
77; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[3].X, PS
78; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].W, PS
79
80; UNSAFE-FP: v_rcp_f32
81; UNSAFE-FP: v_rcp_f32
82; UNSAFE-FP: v_mul_f32_e32
83; UNSAFE-FP: v_mul_f32_e32
84
85; SI-DAG: v_rcp_f32
86; SI-DAG: v_mul_f32
87; SI-DAG: v_rcp_f32
88; SI-DAG: v_mul_f32
89
90; I754: v_div_scale_f32
91; I754: v_div_scale_f32
92; I754: v_div_scale_f32
93; I754: v_div_scale_f32
94; I754: v_div_fixup_f32
95; I754: v_div_fixup_f32
96define void @fdiv_v2f32(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) {
97entry:
98  %0 = fdiv <2 x float> %a, %b
99  store <2 x float> %0, <2 x float> addrspace(1)* %out
100  ret void
101}
102
103; FUNC-LABEL: {{^}}fdiv_v2f32_fast_math:
104; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Z
105; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Y
106; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[3].X, PS
107; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].W, PS
108
109; UNSAFE-FP: v_rcp_f32
110; UNSAFE-FP: v_rcp_f32
111; UNSAFE-FP: v_mul_f32_e32
112; UNSAFE-FP: v_mul_f32_e32
113
114; SI-DAG: v_rcp_f32
115; SI-DAG: v_mul_f32
116; SI-DAG: v_rcp_f32
117; SI-DAG: v_mul_f32
118define void @fdiv_v2f32_fast_math(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) {
119entry:
120  %0 = fdiv fast <2 x float> %a, %b
121  store <2 x float> %0, <2 x float> addrspace(1)* %out
122  ret void
123}
124
125; FUNC-LABEL: {{^}}fdiv_v2f32_arcp_math:
126; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Z
127; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[3].Y
128; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[3].X, PS
129; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].W, PS
130
131; UNSAFE-FP: v_rcp_f32
132; UNSAFE-FP: v_rcp_f32
133; UNSAFE-FP: v_mul_f32_e32
134; UNSAFE-FP: v_mul_f32_e32
135
136; SI-DAG: v_rcp_f32
137; SI-DAG: v_mul_f32
138; SI-DAG: v_rcp_f32
139; SI-DAG: v_mul_f32
140define void @fdiv_v2f32_arcp_math(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) {
141entry:
142  %0 = fdiv arcp <2 x float> %a, %b
143  store <2 x float> %0, <2 x float> addrspace(1)* %out
144  ret void
145}
146
147; FUNC-LABEL: {{^}}fdiv_v4f32:
148; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
149; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
150; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
151; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
152; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
153; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
154; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
155; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
156
157; UNSAFE-FP: v_rcp_f32_e32
158; UNSAFE-FP: v_rcp_f32_e32
159; UNSAFE-FP: v_rcp_f32_e32
160; UNSAFE-FP: v_rcp_f32_e32
161; UNSAFE-FP: v_mul_f32_e32
162; UNSAFE-FP: v_mul_f32_e32
163; UNSAFE-FP: v_mul_f32_e32
164; UNSAFE-FP: v_mul_f32_e32
165
166; SI-DAG: v_rcp_f32
167; SI-DAG: v_mul_f32
168; SI-DAG: v_rcp_f32
169; SI-DAG: v_mul_f32
170; SI-DAG: v_rcp_f32
171; SI-DAG: v_mul_f32
172; SI-DAG: v_rcp_f32
173; SI-DAG: v_mul_f32
174
175; I754: v_div_scale_f32
176; I754: v_div_scale_f32
177; I754: v_div_scale_f32
178; I754: v_div_scale_f32
179; I754: v_div_scale_f32
180; I754: v_div_scale_f32
181; I754: v_div_scale_f32
182; I754: v_div_scale_f32
183; I754: v_div_fixup_f32
184; I754: v_div_fixup_f32
185; I754: v_div_fixup_f32
186; I754: v_div_fixup_f32
187define void @fdiv_v4f32(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) {
188  %b_ptr = getelementptr <4 x float>, <4 x float> addrspace(1)* %in, i32 1
189  %a = load <4 x float>, <4 x float> addrspace(1) * %in
190  %b = load <4 x float>, <4 x float> addrspace(1) * %b_ptr
191  %result = fdiv <4 x float> %a, %b
192  store <4 x float> %result, <4 x float> addrspace(1)* %out
193  ret void
194}
195
196; FUNC-LABEL: {{^}}fdiv_v4f32_fast_math:
197; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
198; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
199; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
200; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
201; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
202; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
203; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
204; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
205
206; UNSAFE-FP: v_rcp_f32_e32
207; UNSAFE-FP: v_rcp_f32_e32
208; UNSAFE-FP: v_rcp_f32_e32
209; UNSAFE-FP: v_rcp_f32_e32
210; UNSAFE-FP: v_mul_f32_e32
211; UNSAFE-FP: v_mul_f32_e32
212; UNSAFE-FP: v_mul_f32_e32
213; UNSAFE-FP: v_mul_f32_e32
214
215; SI-DAG: v_rcp_f32
216; SI-DAG: v_mul_f32
217; SI-DAG: v_rcp_f32
218; SI-DAG: v_mul_f32
219; SI-DAG: v_rcp_f32
220; SI-DAG: v_mul_f32
221; SI-DAG: v_rcp_f32
222; SI-DAG: v_mul_f32
223define void @fdiv_v4f32_fast_math(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) {
224  %b_ptr = getelementptr <4 x float>, <4 x float> addrspace(1)* %in, i32 1
225  %a = load <4 x float>, <4 x float> addrspace(1) * %in
226  %b = load <4 x float>, <4 x float> addrspace(1) * %b_ptr
227  %result = fdiv fast <4 x float> %a, %b
228  store <4 x float> %result, <4 x float> addrspace(1)* %out
229  ret void
230}
231
232; FUNC-LABEL: {{^}}fdiv_v4f32_arcp_math:
233; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
234; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
235; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
236; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
237; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
238; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
239; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
240; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
241
242; UNSAFE-FP: v_rcp_f32_e32
243; UNSAFE-FP: v_rcp_f32_e32
244; UNSAFE-FP: v_rcp_f32_e32
245; UNSAFE-FP: v_rcp_f32_e32
246; UNSAFE-FP: v_mul_f32_e32
247; UNSAFE-FP: v_mul_f32_e32
248; UNSAFE-FP: v_mul_f32_e32
249; UNSAFE-FP: v_mul_f32_e32
250
251; SI-DAG: v_rcp_f32
252; SI-DAG: v_mul_f32
253; SI-DAG: v_rcp_f32
254; SI-DAG: v_mul_f32
255; SI-DAG: v_rcp_f32
256; SI-DAG: v_mul_f32
257; SI-DAG: v_rcp_f32
258; SI-DAG: v_mul_f32
259define void @fdiv_v4f32_arcp_math(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) {
260  %b_ptr = getelementptr <4 x float>, <4 x float> addrspace(1)* %in, i32 1
261  %a = load <4 x float>, <4 x float> addrspace(1) * %in
262  %b = load <4 x float>, <4 x float> addrspace(1) * %b_ptr
263  %result = fdiv arcp <4 x float> %a, %b
264  store <4 x float> %result, <4 x float> addrspace(1)* %out
265  ret void
266}
267