1; RUN: opt -S -mtriple=amdgcn-- -amdgpu-codegenprepare %s | FileCheck %s
2; RUN: opt -S -amdgpu-codegenprepare %s | FileCheck -check-prefix=NOOP %s
3; Make sure this doesn't crash with no triple
4
5; NOOP-LABEL: @noop_fdiv_fpmath(
6; NOOP: %md.25ulp = fdiv float %a, %b, !fpmath !0
7define void @noop_fdiv_fpmath(float addrspace(1)* %out, float %a, float %b) #3 {
8  %md.25ulp = fdiv float %a, %b, !fpmath !0
9  store volatile float %md.25ulp, float addrspace(1)* %out
10  ret void
11}
12
13; CHECK-LABEL: @fdiv_fpmath(
14; CHECK: %no.md = fdiv float %a, %b{{$}}
15; CHECK: %md.half.ulp = fdiv float %a, %b, !fpmath !1
16; CHECK: %md.1ulp = fdiv float %a, %b, !fpmath !2
17; CHECK: %md.25ulp = call float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !0
18; CHECK: %md.3ulp = call float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !3
19; CHECK: %fast.md.25ulp = call fast float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !0
20; CHECK: arcp.md.25ulp = call arcp float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !0
21define void @fdiv_fpmath(float addrspace(1)* %out, float %a, float %b) #1 {
22  %no.md = fdiv float %a, %b
23  store volatile float %no.md, float addrspace(1)* %out
24
25  %md.half.ulp = fdiv float %a, %b, !fpmath !1
26  store volatile float %md.half.ulp, float addrspace(1)* %out
27
28  %md.1ulp = fdiv float %a, %b, !fpmath !2
29  store volatile float %md.1ulp, float addrspace(1)* %out
30
31  %md.25ulp = fdiv float %a, %b, !fpmath !0
32  store volatile float %md.25ulp, float addrspace(1)* %out
33
34  %md.3ulp = fdiv float %a, %b, !fpmath !3
35  store volatile float %md.3ulp, float addrspace(1)* %out
36
37  %fast.md.25ulp = fdiv fast float %a, %b, !fpmath !0
38  store volatile float %fast.md.25ulp, float addrspace(1)* %out
39
40  %arcp.md.25ulp = fdiv arcp float %a, %b, !fpmath !0
41  store volatile float %arcp.md.25ulp, float addrspace(1)* %out
42
43  ret void
44}
45
46; CHECK-LABEL: @rcp_fdiv_fpmath(
47; CHECK: %no.md = fdiv float 1.000000e+00, %x{{$}}
48; CHECK: %md.25ulp = fdiv float 1.000000e+00, %x, !fpmath !0
49; CHECK: %md.half.ulp = fdiv float 1.000000e+00, %x, !fpmath !1
50; CHECK: %arcp.no.md = fdiv arcp float 1.000000e+00, %x{{$}}
51; CHECK: %arcp.25ulp = fdiv arcp float 1.000000e+00, %x, !fpmath !0
52; CHECK: %fast.no.md = fdiv fast float 1.000000e+00, %x{{$}}
53; CHECK: %fast.25ulp = fdiv fast float 1.000000e+00, %x, !fpmath !0
54define void @rcp_fdiv_fpmath(float addrspace(1)* %out, float %x) #1 {
55  %no.md = fdiv float 1.0, %x
56  store volatile float %no.md, float addrspace(1)* %out
57
58  %md.25ulp = fdiv float 1.0, %x, !fpmath !0
59  store volatile float %md.25ulp, float addrspace(1)* %out
60
61  %md.half.ulp = fdiv float 1.0, %x, !fpmath !1
62  store volatile float %md.half.ulp, float addrspace(1)* %out
63
64  %arcp.no.md = fdiv arcp float 1.0, %x
65  store volatile float %arcp.no.md, float addrspace(1)* %out
66
67  %arcp.25ulp = fdiv arcp float 1.0, %x, !fpmath !0
68  store volatile float %arcp.25ulp, float addrspace(1)* %out
69
70  %fast.no.md = fdiv fast float 1.0, %x
71  store volatile float %fast.no.md, float addrspace(1)* %out
72
73  %fast.25ulp = fdiv fast float 1.0, %x, !fpmath !0
74  store volatile float %fast.25ulp, float addrspace(1)* %out
75
76  ret void
77}
78
79; CHECK-LABEL: @fdiv_fpmath_vector(
80; CHECK: %no.md = fdiv <2 x float> %a, %b{{$}}
81; CHECK: %md.half.ulp = fdiv <2 x float> %a, %b, !fpmath !1
82; CHECK: %md.1ulp = fdiv <2 x float> %a, %b, !fpmath !2
83
84; CHECK: %[[A0:[0-9]+]] = extractelement <2 x float> %a, i64 0
85; CHECK: %[[B0:[0-9]+]] = extractelement <2 x float> %b, i64 0
86; CHECK: %[[FDIV0:[0-9]+]] = call float @llvm.amdgcn.fdiv.fast(float %[[A0]], float %[[B0]]), !fpmath !0
87; CHECK: %[[INS0:[0-9]+]] = insertelement <2 x float> undef, float %[[FDIV0]], i64 0
88; CHECK: %[[A1:[0-9]+]] = extractelement <2 x float> %a, i64 1
89; CHECK: %[[B1:[0-9]+]] = extractelement <2 x float> %b, i64 1
90; CHECK: %[[FDIV1:[0-9]+]] = call float @llvm.amdgcn.fdiv.fast(float %[[A1]], float %[[B1]]), !fpmath !0
91; CHECK: %md.25ulp = insertelement <2 x float> %[[INS0]], float %[[FDIV1]], i64 1
92define void @fdiv_fpmath_vector(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) #1 {
93  %no.md = fdiv <2 x float> %a, %b
94  store volatile <2 x float> %no.md, <2 x float> addrspace(1)* %out
95
96  %md.half.ulp = fdiv <2 x float> %a, %b, !fpmath !1
97  store volatile <2 x float> %md.half.ulp, <2 x float> addrspace(1)* %out
98
99  %md.1ulp = fdiv <2 x float> %a, %b, !fpmath !2
100  store volatile <2 x float> %md.1ulp, <2 x float> addrspace(1)* %out
101
102  %md.25ulp = fdiv <2 x float> %a, %b, !fpmath !0
103  store volatile <2 x float> %md.25ulp, <2 x float> addrspace(1)* %out
104
105  ret void
106}
107
108; CHECK-LABEL: @rcp_fdiv_fpmath_vector(
109; CHECK: %no.md = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, %x{{$}}
110; CHECK: %md.half.ulp = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, %x, !fpmath !1
111; CHECK: %arcp.no.md = fdiv arcp <2 x float> <float 1.000000e+00, float 1.000000e+00>, %x{{$}}
112; CHECK: %fast.no.md = fdiv fast <2 x float> <float 1.000000e+00, float 1.000000e+00>, %x{{$}}
113
114; CHECK: extractelement <2 x float> %x
115; CHECK: fdiv arcp float 1.000000e+00, %{{[0-9]+}}, !fpmath !0
116; CHECK: extractelement <2 x float> %x
117; CHECK: fdiv arcp float 1.000000e+00, %{{[0-9]+}}, !fpmath !0
118; CHECK: store volatile <2 x float> %arcp.25ulp
119
120; CHECK: fdiv fast float 1.000000e+00, %{{[0-9]+}}, !fpmath !0
121; CHECK: fdiv fast float 1.000000e+00, %{{[0-9]+}}, !fpmath !0
122; CHECK: store volatile <2 x float> %fast.25ulp, <2 x float> addrspace(1)* %out
123define void @rcp_fdiv_fpmath_vector(<2 x float> addrspace(1)* %out, <2 x float> %x) #1 {
124  %no.md = fdiv <2 x float> <float 1.0, float 1.0>, %x
125  store volatile <2 x float> %no.md, <2 x float> addrspace(1)* %out
126
127  %md.half.ulp = fdiv <2 x float> <float 1.0, float 1.0>, %x, !fpmath !1
128  store volatile <2 x float> %md.half.ulp, <2 x float> addrspace(1)* %out
129
130  %arcp.no.md = fdiv arcp <2 x float> <float 1.0, float 1.0>, %x
131  store volatile <2 x float> %arcp.no.md, <2 x float> addrspace(1)* %out
132
133  %fast.no.md = fdiv fast <2 x float> <float 1.0, float 1.0>, %x
134  store volatile <2 x float> %fast.no.md, <2 x float> addrspace(1)* %out
135
136  %arcp.25ulp = fdiv arcp <2 x float> <float 1.0, float 1.0>, %x, !fpmath !0
137  store volatile <2 x float> %arcp.25ulp, <2 x float> addrspace(1)* %out
138
139  %fast.25ulp = fdiv fast <2 x float> <float 1.0, float 1.0>, %x, !fpmath !0
140  store volatile <2 x float> %fast.25ulp, <2 x float> addrspace(1)* %out
141
142  ret void
143}
144
145; CHECK-LABEL: @rcp_fdiv_fpmath_vector_nonsplat(
146; CHECK: %no.md = fdiv <2 x float> <float 1.000000e+00, float 2.000000e+00>, %x
147; CHECK: %arcp.no.md = fdiv arcp <2 x float> <float 1.000000e+00, float 2.000000e+00>, %x
148; CHECK: %fast.no.md = fdiv fast <2 x float> <float 1.000000e+00, float 2.000000e+00>, %x{{$}}
149
150; CHECK: %[[X0:[0-9]+]] = extractelement <2 x float> %x, i64 0
151; CHECK: fdiv arcp float 1.000000e+00, %[[X0]], !fpmath !0
152; CHECK: %[[X1:[0-9]+]] = extractelement <2 x float> %x, i64 1
153; CHECK: fdiv arcp float 2.000000e+00, %[[X1]], !fpmath !0
154; CHECK: store volatile <2 x float> %arcp.25ulp
155
156; CHECK: %[[X0:[0-9]+]] = extractelement <2 x float> %x, i64 0
157; CHECK: fdiv fast float 1.000000e+00, %[[X0]], !fpmath !0
158; CHECK: %[[X1:[0-9]+]] = extractelement <2 x float> %x, i64 1
159; CHECK: fdiv fast float 2.000000e+00, %[[X1]], !fpmath !0
160; CHECK: store volatile <2 x float> %fast.25ulp
161define void @rcp_fdiv_fpmath_vector_nonsplat(<2 x float> addrspace(1)* %out, <2 x float> %x) #1 {
162  %no.md = fdiv <2 x float> <float 1.0, float 2.0>, %x
163  store volatile <2 x float> %no.md, <2 x float> addrspace(1)* %out
164
165  %arcp.no.md = fdiv arcp <2 x float> <float 1.0, float 2.0>, %x
166  store volatile <2 x float> %arcp.no.md, <2 x float> addrspace(1)* %out
167
168  %fast.no.md = fdiv fast <2 x float> <float 1.0, float 2.0>, %x
169  store volatile <2 x float> %fast.no.md, <2 x float> addrspace(1)* %out
170
171  %arcp.25ulp = fdiv arcp <2 x float> <float 1.0, float 2.0>, %x, !fpmath !0
172  store volatile <2 x float> %arcp.25ulp, <2 x float> addrspace(1)* %out
173
174  %fast.25ulp = fdiv fast <2 x float> <float 1.0, float 2.0>, %x, !fpmath !0
175  store volatile <2 x float> %fast.25ulp, <2 x float> addrspace(1)* %out
176
177  ret void
178}
179
180; FIXME: Should be able to get fdiv for 1.0 component
181; CHECK-LABEL: @rcp_fdiv_fpmath_vector_partial_constant(
182; CHECK: call arcp float @llvm.amdgcn.fdiv.fast(float %{{[0-9]+}}, float %{{[0-9]+}}), !fpmath !0
183; CHECK: call arcp float @llvm.amdgcn.fdiv.fast(float %{{[0-9]+}}, float %{{[0-9]+}}), !fpmath !0
184; CHECK: store volatile <2 x float> %arcp.25ulp
185
186; CHECK: call fast float @llvm.amdgcn.fdiv.fast(float %{{[0-9]+}}, float %{{[0-9]+}}), !fpmath !0
187; CHECK: call fast float @llvm.amdgcn.fdiv.fast(float %{{[0-9]+}}, float %{{[0-9]+}}), !fpmath !0
188; CHECK: store volatile <2 x float> %fast.25ulp
189define void @rcp_fdiv_fpmath_vector_partial_constant(<2 x float> addrspace(1)* %out, <2 x float> %x, <2 x float> %y) #1 {
190  %x.insert = insertelement <2 x float> %x, float 1.0, i32 0
191
192  %arcp.25ulp = fdiv arcp <2 x float> %x.insert, %y, !fpmath !0
193  store volatile <2 x float> %arcp.25ulp, <2 x float> addrspace(1)* %out
194
195  %fast.25ulp = fdiv fast <2 x float> %x.insert, %y, !fpmath !0
196  store volatile <2 x float> %fast.25ulp, <2 x float> addrspace(1)* %out
197
198  ret void
199}
200
201; CHECK-LABEL: @fdiv_fpmath_f32_denormals(
202; CHECK: %no.md = fdiv float %a, %b{{$}}
203; CHECK: %md.half.ulp = fdiv float %a, %b, !fpmath !1
204; CHECK: %md.1ulp = fdiv float %a, %b, !fpmath !2
205; CHECK: %md.25ulp = fdiv float %a, %b, !fpmath !0
206; CHECK: %md.3ulp = fdiv float %a, %b, !fpmath !3
207; CHECK: call fast float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !0
208; CHECK: call arcp float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !0
209define void @fdiv_fpmath_f32_denormals(float addrspace(1)* %out, float %a, float %b) #2 {
210  %no.md = fdiv float %a, %b
211  store volatile float %no.md, float addrspace(1)* %out
212
213  %md.half.ulp = fdiv float %a, %b, !fpmath !1
214  store volatile float %md.half.ulp, float addrspace(1)* %out
215
216  %md.1ulp = fdiv float %a, %b, !fpmath !2
217  store volatile float %md.1ulp, float addrspace(1)* %out
218
219  %md.25ulp = fdiv float %a, %b, !fpmath !0
220  store volatile float %md.25ulp, float addrspace(1)* %out
221
222  %md.3ulp = fdiv float %a, %b, !fpmath !3
223  store volatile float %md.3ulp, float addrspace(1)* %out
224
225  %fast.md.25ulp = fdiv fast float %a, %b, !fpmath !0
226  store volatile float %fast.md.25ulp, float addrspace(1)* %out
227
228  %arcp.md.25ulp = fdiv arcp float %a, %b, !fpmath !0
229  store volatile float %arcp.md.25ulp, float addrspace(1)* %out
230
231  ret void
232}
233
234attributes #0 = { nounwind optnone noinline }
235attributes #1 = { nounwind }
236attributes #2 = { nounwind "target-features"="+fp32-denormals" }
237
238; CHECK: !0 = !{float 2.500000e+00}
239; CHECK: !1 = !{float 5.000000e-01}
240; CHECK: !2 = !{float 1.000000e+00}
241; CHECK: !3 = !{float 3.000000e+00}
242
243!0 = !{float 2.500000e+00}
244!1 = !{float 5.000000e-01}
245!2 = !{float 1.000000e+00}
246!3 = !{float 3.000000e+00}
247