1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64 -mattr=+sse2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE
3; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64 -mattr=+avx  | FileCheck %s --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX1
4; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64 -mattr=+avx512f  | FileCheck %s --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX512
5
6declare double @__sqrt_finite(double)
7declare float @__sqrtf_finite(float)
8declare x86_fp80 @__sqrtl_finite(x86_fp80)
9declare float @llvm.sqrt.f32(float)
10declare <4 x float> @llvm.sqrt.v4f32(<4 x float>)
11declare <8 x float> @llvm.sqrt.v8f32(<8 x float>)
12declare <16 x float> @llvm.sqrt.v16f32(<16 x float>)
13
14
15define double @finite_f64_no_estimate(double %d) #0 {
16; SSE-LABEL: finite_f64_no_estimate:
17; SSE:       # %bb.0:
18; SSE-NEXT:    sqrtsd %xmm0, %xmm0
19; SSE-NEXT:    retq
20;
21; AVX-LABEL: finite_f64_no_estimate:
22; AVX:       # %bb.0:
23; AVX-NEXT:    vsqrtsd %xmm0, %xmm0, %xmm0
24; AVX-NEXT:    retq
25  %call = tail call double @__sqrt_finite(double %d) #2
26  ret double %call
27}
28
29; No estimates for doubles.
30
31define double @finite_f64_estimate(double %d) #1 {
32; SSE-LABEL: finite_f64_estimate:
33; SSE:       # %bb.0:
34; SSE-NEXT:    sqrtsd %xmm0, %xmm0
35; SSE-NEXT:    retq
36;
37; AVX-LABEL: finite_f64_estimate:
38; AVX:       # %bb.0:
39; AVX-NEXT:    vsqrtsd %xmm0, %xmm0, %xmm0
40; AVX-NEXT:    retq
41  %call = tail call double @__sqrt_finite(double %d) #2
42  ret double %call
43}
44
45define float @finite_f32_no_estimate(float %f) #0 {
46; SSE-LABEL: finite_f32_no_estimate:
47; SSE:       # %bb.0:
48; SSE-NEXT:    sqrtss %xmm0, %xmm0
49; SSE-NEXT:    retq
50;
51; AVX-LABEL: finite_f32_no_estimate:
52; AVX:       # %bb.0:
53; AVX-NEXT:    vsqrtss %xmm0, %xmm0, %xmm0
54; AVX-NEXT:    retq
55  %call = tail call float @__sqrtf_finite(float %f) #2
56  ret float %call
57}
58
59define float @finite_f32_estimate_ieee(float %f) #1 {
60; SSE-LABEL: finite_f32_estimate_ieee:
61; SSE:       # %bb.0:
62; SSE-NEXT:    sqrtss %xmm0, %xmm0
63; SSE-NEXT:    retq
64;
65; AVX-LABEL: finite_f32_estimate_ieee:
66; AVX:       # %bb.0:
67; AVX-NEXT:    vsqrtss %xmm0, %xmm0, %xmm0
68; AVX-NEXT:    retq
69  %call = tail call float @__sqrtf_finite(float %f) #2
70  ret float %call
71}
72
73define float @finite_f32_estimate_ieee_ninf(float %f) #1 {
74; SSE-LABEL: finite_f32_estimate_ieee_ninf:
75; SSE:       # %bb.0:
76; SSE-NEXT:    rsqrtss %xmm0, %xmm1
77; SSE-NEXT:    movaps %xmm0, %xmm2
78; SSE-NEXT:    mulss %xmm1, %xmm2
79; SSE-NEXT:    movss {{.*#+}} xmm3 = mem[0],zero,zero,zero
80; SSE-NEXT:    mulss %xmm2, %xmm3
81; SSE-NEXT:    mulss %xmm1, %xmm2
82; SSE-NEXT:    addss {{.*}}(%rip), %xmm2
83; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
84; SSE-NEXT:    mulss %xmm3, %xmm2
85; SSE-NEXT:    cmpltss {{.*}}(%rip), %xmm0
86; SSE-NEXT:    andnps %xmm2, %xmm0
87; SSE-NEXT:    retq
88;
89; AVX1-LABEL: finite_f32_estimate_ieee_ninf:
90; AVX1:       # %bb.0:
91; AVX1-NEXT:    vrsqrtss %xmm0, %xmm0, %xmm1
92; AVX1-NEXT:    vmulss %xmm1, %xmm0, %xmm2
93; AVX1-NEXT:    vmulss %xmm1, %xmm2, %xmm1
94; AVX1-NEXT:    vaddss {{.*}}(%rip), %xmm1, %xmm1
95; AVX1-NEXT:    vmulss {{.*}}(%rip), %xmm2, %xmm2
96; AVX1-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
97; AVX1-NEXT:    vmulss %xmm1, %xmm2, %xmm1
98; AVX1-NEXT:    vcmpltss {{.*}}(%rip), %xmm0, %xmm0
99; AVX1-NEXT:    vandnps %xmm1, %xmm0, %xmm0
100; AVX1-NEXT:    retq
101;
102; AVX512-LABEL: finite_f32_estimate_ieee_ninf:
103; AVX512:       # %bb.0:
104; AVX512-NEXT:    vrsqrtss %xmm0, %xmm0, %xmm1
105; AVX512-NEXT:    vmulss %xmm1, %xmm0, %xmm2
106; AVX512-NEXT:    vfmadd213ss {{.*#+}} xmm1 = (xmm2 * xmm1) + mem
107; AVX512-NEXT:    vmulss {{.*}}(%rip), %xmm2, %xmm2
108; AVX512-NEXT:    vmulss %xmm1, %xmm2, %xmm1
109; AVX512-NEXT:    vbroadcastss {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN]
110; AVX512-NEXT:    vandps %xmm2, %xmm0, %xmm0
111; AVX512-NEXT:    vcmpltss {{.*}}(%rip), %xmm0, %k1
112; AVX512-NEXT:    vxorps %xmm0, %xmm0, %xmm0
113; AVX512-NEXT:    vmovss %xmm0, %xmm1, %xmm1 {%k1}
114; AVX512-NEXT:    vmovaps %xmm1, %xmm0
115; AVX512-NEXT:    retq
116  %call = tail call ninf float @__sqrtf_finite(float %f) #2
117  ret float %call
118}
119
120define float @finite_f32_estimate_daz(float %f) #4 {
121; SSE-LABEL: finite_f32_estimate_daz:
122; SSE:       # %bb.0:
123; SSE-NEXT:    sqrtss %xmm0, %xmm0
124; SSE-NEXT:    retq
125;
126; AVX-LABEL: finite_f32_estimate_daz:
127; AVX:       # %bb.0:
128; AVX-NEXT:    vsqrtss %xmm0, %xmm0, %xmm0
129; AVX-NEXT:    retq
130  %call = tail call float @__sqrtf_finite(float %f) #2
131  ret float %call
132}
133
134define float @finite_f32_estimate_daz_ninf(float %f) #4 {
135; SSE-LABEL: finite_f32_estimate_daz_ninf:
136; SSE:       # %bb.0:
137; SSE-NEXT:    rsqrtss %xmm0, %xmm1
138; SSE-NEXT:    movaps %xmm0, %xmm2
139; SSE-NEXT:    mulss %xmm1, %xmm2
140; SSE-NEXT:    movss {{.*#+}} xmm3 = mem[0],zero,zero,zero
141; SSE-NEXT:    mulss %xmm2, %xmm3
142; SSE-NEXT:    mulss %xmm1, %xmm2
143; SSE-NEXT:    addss {{.*}}(%rip), %xmm2
144; SSE-NEXT:    mulss %xmm3, %xmm2
145; SSE-NEXT:    xorps %xmm1, %xmm1
146; SSE-NEXT:    cmpeqss %xmm1, %xmm0
147; SSE-NEXT:    andnps %xmm2, %xmm0
148; SSE-NEXT:    retq
149;
150; AVX1-LABEL: finite_f32_estimate_daz_ninf:
151; AVX1:       # %bb.0:
152; AVX1-NEXT:    vrsqrtss %xmm0, %xmm0, %xmm1
153; AVX1-NEXT:    vmulss %xmm1, %xmm0, %xmm2
154; AVX1-NEXT:    vmulss %xmm1, %xmm2, %xmm1
155; AVX1-NEXT:    vaddss {{.*}}(%rip), %xmm1, %xmm1
156; AVX1-NEXT:    vmulss {{.*}}(%rip), %xmm2, %xmm2
157; AVX1-NEXT:    vmulss %xmm1, %xmm2, %xmm1
158; AVX1-NEXT:    vxorps %xmm2, %xmm2, %xmm2
159; AVX1-NEXT:    vcmpeqss %xmm2, %xmm0, %xmm0
160; AVX1-NEXT:    vandnps %xmm1, %xmm0, %xmm0
161; AVX1-NEXT:    retq
162;
163; AVX512-LABEL: finite_f32_estimate_daz_ninf:
164; AVX512:       # %bb.0:
165; AVX512-NEXT:    vrsqrtss %xmm0, %xmm0, %xmm1
166; AVX512-NEXT:    vmulss %xmm1, %xmm0, %xmm2
167; AVX512-NEXT:    vfmadd213ss {{.*#+}} xmm1 = (xmm2 * xmm1) + mem
168; AVX512-NEXT:    vmulss {{.*}}(%rip), %xmm2, %xmm2
169; AVX512-NEXT:    vmulss %xmm1, %xmm2, %xmm1
170; AVX512-NEXT:    vxorps %xmm2, %xmm2, %xmm2
171; AVX512-NEXT:    vcmpeqss %xmm2, %xmm0, %k1
172; AVX512-NEXT:    vmovss %xmm2, %xmm1, %xmm1 {%k1}
173; AVX512-NEXT:    vmovaps %xmm1, %xmm0
174; AVX512-NEXT:    retq
175  %call = tail call ninf float @__sqrtf_finite(float %f) #2
176  ret float %call
177}
178
179define x86_fp80 @finite_f80_no_estimate(x86_fp80 %ld) #0 {
180; CHECK-LABEL: finite_f80_no_estimate:
181; CHECK:       # %bb.0:
182; CHECK-NEXT:    fldt {{[0-9]+}}(%rsp)
183; CHECK-NEXT:    fsqrt
184; CHECK-NEXT:    retq
185  %call = tail call x86_fp80 @__sqrtl_finite(x86_fp80 %ld) #2
186  ret x86_fp80 %call
187}
188
189; Don't die on the impossible.
190
191define x86_fp80 @finite_f80_estimate_but_no(x86_fp80 %ld) #1 {
192; CHECK-LABEL: finite_f80_estimate_but_no:
193; CHECK:       # %bb.0:
194; CHECK-NEXT:    fldt {{[0-9]+}}(%rsp)
195; CHECK-NEXT:    fsqrt
196; CHECK-NEXT:    retq
197  %call = tail call x86_fp80 @__sqrtl_finite(x86_fp80 %ld) #2
198  ret x86_fp80 %call
199}
200
201; PR34994 - https://bugs.llvm.org/show_bug.cgi?id=34994
202
203define float @sqrtf_check_denorms(float %x) #3 {
204; SSE-LABEL: sqrtf_check_denorms:
205; SSE:       # %bb.0:
206; SSE-NEXT:    sqrtss %xmm0, %xmm0
207; SSE-NEXT:    retq
208;
209; AVX-LABEL: sqrtf_check_denorms:
210; AVX:       # %bb.0:
211; AVX-NEXT:    vsqrtss %xmm0, %xmm0, %xmm0
212; AVX-NEXT:    retq
213  %call = tail call float @__sqrtf_finite(float %x) #2
214  ret float %call
215}
216
217define float @sqrtf_check_denorms_ninf(float %x) #3 {
218; SSE-LABEL: sqrtf_check_denorms_ninf:
219; SSE:       # %bb.0:
220; SSE-NEXT:    rsqrtss %xmm0, %xmm1
221; SSE-NEXT:    movaps %xmm0, %xmm2
222; SSE-NEXT:    mulss %xmm1, %xmm2
223; SSE-NEXT:    movss {{.*#+}} xmm3 = mem[0],zero,zero,zero
224; SSE-NEXT:    mulss %xmm2, %xmm3
225; SSE-NEXT:    mulss %xmm1, %xmm2
226; SSE-NEXT:    addss {{.*}}(%rip), %xmm2
227; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
228; SSE-NEXT:    mulss %xmm3, %xmm2
229; SSE-NEXT:    cmpltss {{.*}}(%rip), %xmm0
230; SSE-NEXT:    andnps %xmm2, %xmm0
231; SSE-NEXT:    retq
232;
233; AVX1-LABEL: sqrtf_check_denorms_ninf:
234; AVX1:       # %bb.0:
235; AVX1-NEXT:    vrsqrtss %xmm0, %xmm0, %xmm1
236; AVX1-NEXT:    vmulss %xmm1, %xmm0, %xmm2
237; AVX1-NEXT:    vmulss %xmm1, %xmm2, %xmm1
238; AVX1-NEXT:    vaddss {{.*}}(%rip), %xmm1, %xmm1
239; AVX1-NEXT:    vmulss {{.*}}(%rip), %xmm2, %xmm2
240; AVX1-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
241; AVX1-NEXT:    vmulss %xmm1, %xmm2, %xmm1
242; AVX1-NEXT:    vcmpltss {{.*}}(%rip), %xmm0, %xmm0
243; AVX1-NEXT:    vandnps %xmm1, %xmm0, %xmm0
244; AVX1-NEXT:    retq
245;
246; AVX512-LABEL: sqrtf_check_denorms_ninf:
247; AVX512:       # %bb.0:
248; AVX512-NEXT:    vrsqrtss %xmm0, %xmm0, %xmm1
249; AVX512-NEXT:    vmulss %xmm1, %xmm0, %xmm2
250; AVX512-NEXT:    vfmadd213ss {{.*#+}} xmm1 = (xmm2 * xmm1) + mem
251; AVX512-NEXT:    vmulss {{.*}}(%rip), %xmm2, %xmm2
252; AVX512-NEXT:    vmulss %xmm1, %xmm2, %xmm1
253; AVX512-NEXT:    vbroadcastss {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN]
254; AVX512-NEXT:    vandps %xmm2, %xmm0, %xmm0
255; AVX512-NEXT:    vcmpltss {{.*}}(%rip), %xmm0, %k1
256; AVX512-NEXT:    vxorps %xmm0, %xmm0, %xmm0
257; AVX512-NEXT:    vmovss %xmm0, %xmm1, %xmm1 {%k1}
258; AVX512-NEXT:    vmovaps %xmm1, %xmm0
259; AVX512-NEXT:    retq
260  %call = tail call ninf float @__sqrtf_finite(float %x) #2
261  ret float %call
262}
263
264define <4 x float> @sqrt_v4f32_check_denorms(<4 x float> %x) #3 {
265; SSE-LABEL: sqrt_v4f32_check_denorms:
266; SSE:       # %bb.0:
267; SSE-NEXT:    sqrtps %xmm0, %xmm0
268; SSE-NEXT:    retq
269;
270; AVX-LABEL: sqrt_v4f32_check_denorms:
271; AVX:       # %bb.0:
272; AVX-NEXT:    vsqrtps %xmm0, %xmm0
273; AVX-NEXT:    retq
274  %call = tail call <4 x float> @llvm.sqrt.v4f32(<4 x float> %x) #2
275  ret <4 x float> %call
276}
277
278define <4 x float> @sqrt_v4f32_check_denorms_ninf(<4 x float> %x) #3 {
279; SSE-LABEL: sqrt_v4f32_check_denorms_ninf:
280; SSE:       # %bb.0:
281; SSE-NEXT:    rsqrtps %xmm0, %xmm2
282; SSE-NEXT:    movaps %xmm0, %xmm1
283; SSE-NEXT:    mulps %xmm2, %xmm1
284; SSE-NEXT:    movaps {{.*#+}} xmm3 = [-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1]
285; SSE-NEXT:    mulps %xmm1, %xmm3
286; SSE-NEXT:    mulps %xmm2, %xmm1
287; SSE-NEXT:    addps {{.*}}(%rip), %xmm1
288; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
289; SSE-NEXT:    mulps %xmm3, %xmm1
290; SSE-NEXT:    movaps {{.*#+}} xmm2 = [1.17549435E-38,1.17549435E-38,1.17549435E-38,1.17549435E-38]
291; SSE-NEXT:    cmpleps %xmm0, %xmm2
292; SSE-NEXT:    andps %xmm2, %xmm1
293; SSE-NEXT:    movaps %xmm1, %xmm0
294; SSE-NEXT:    retq
295;
296; AVX1-LABEL: sqrt_v4f32_check_denorms_ninf:
297; AVX1:       # %bb.0:
298; AVX1-NEXT:    vrsqrtps %xmm0, %xmm1
299; AVX1-NEXT:    vmulps %xmm1, %xmm0, %xmm2
300; AVX1-NEXT:    vmulps {{.*}}(%rip), %xmm2, %xmm3
301; AVX1-NEXT:    vmulps %xmm1, %xmm2, %xmm1
302; AVX1-NEXT:    vaddps {{.*}}(%rip), %xmm1, %xmm1
303; AVX1-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
304; AVX1-NEXT:    vmulps %xmm1, %xmm3, %xmm1
305; AVX1-NEXT:    vmovaps {{.*#+}} xmm2 = [1.17549435E-38,1.17549435E-38,1.17549435E-38,1.17549435E-38]
306; AVX1-NEXT:    vcmpleps %xmm0, %xmm2, %xmm0
307; AVX1-NEXT:    vandps %xmm1, %xmm0, %xmm0
308; AVX1-NEXT:    retq
309;
310; AVX512-LABEL: sqrt_v4f32_check_denorms_ninf:
311; AVX512:       # %bb.0:
312; AVX512-NEXT:    vrsqrtps %xmm0, %xmm1
313; AVX512-NEXT:    vmulps %xmm1, %xmm0, %xmm2
314; AVX512-NEXT:    vbroadcastss {{.*#+}} xmm3 = [-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0]
315; AVX512-NEXT:    vfmadd231ps {{.*#+}} xmm3 = (xmm2 * xmm1) + xmm3
316; AVX512-NEXT:    vbroadcastss {{.*#+}} xmm1 = [-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1]
317; AVX512-NEXT:    vmulps %xmm1, %xmm2, %xmm1
318; AVX512-NEXT:    vmulps %xmm3, %xmm1, %xmm1
319; AVX512-NEXT:    vbroadcastss {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN]
320; AVX512-NEXT:    vandps %xmm2, %xmm0, %xmm0
321; AVX512-NEXT:    vbroadcastss {{.*#+}} xmm2 = [1.17549435E-38,1.17549435E-38,1.17549435E-38,1.17549435E-38]
322; AVX512-NEXT:    vcmpleps %xmm0, %xmm2, %xmm0
323; AVX512-NEXT:    vandps %xmm1, %xmm0, %xmm0
324; AVX512-NEXT:    retq
325  %call = tail call ninf <4 x float> @llvm.sqrt.v4f32(<4 x float> %x) #2
326  ret <4 x float> %call
327}
328
329define float @f32_no_estimate(float %x) #0 {
330; SSE-LABEL: f32_no_estimate:
331; SSE:       # %bb.0:
332; SSE-NEXT:    sqrtss %xmm0, %xmm1
333; SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
334; SSE-NEXT:    divss %xmm1, %xmm0
335; SSE-NEXT:    retq
336;
337; AVX-LABEL: f32_no_estimate:
338; AVX:       # %bb.0:
339; AVX-NEXT:    vsqrtss %xmm0, %xmm0, %xmm0
340; AVX-NEXT:    vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero
341; AVX-NEXT:    vdivss %xmm0, %xmm1, %xmm0
342; AVX-NEXT:    retq
343  %sqrt = tail call float @llvm.sqrt.f32(float %x)
344  %div = fdiv fast float 1.0, %sqrt
345  ret float %div
346}
347
348define float @f32_estimate(float %x) #1 {
349; SSE-LABEL: f32_estimate:
350; SSE:       # %bb.0:
351; SSE-NEXT:    rsqrtss %xmm0, %xmm1
352; SSE-NEXT:    mulss %xmm1, %xmm0
353; SSE-NEXT:    mulss %xmm1, %xmm0
354; SSE-NEXT:    addss {{.*}}(%rip), %xmm0
355; SSE-NEXT:    mulss {{.*}}(%rip), %xmm1
356; SSE-NEXT:    mulss %xmm1, %xmm0
357; SSE-NEXT:    retq
358;
359; AVX1-LABEL: f32_estimate:
360; AVX1:       # %bb.0:
361; AVX1-NEXT:    vrsqrtss %xmm0, %xmm0, %xmm1
362; AVX1-NEXT:    vmulss %xmm1, %xmm0, %xmm0
363; AVX1-NEXT:    vmulss %xmm1, %xmm0, %xmm0
364; AVX1-NEXT:    vaddss {{.*}}(%rip), %xmm0, %xmm0
365; AVX1-NEXT:    vmulss {{.*}}(%rip), %xmm1, %xmm1
366; AVX1-NEXT:    vmulss %xmm0, %xmm1, %xmm0
367; AVX1-NEXT:    retq
368;
369; AVX512-LABEL: f32_estimate:
370; AVX512:       # %bb.0:
371; AVX512-NEXT:    vrsqrtss %xmm0, %xmm0, %xmm1
372; AVX512-NEXT:    vmulss %xmm1, %xmm0, %xmm0
373; AVX512-NEXT:    vfmadd213ss {{.*#+}} xmm0 = (xmm1 * xmm0) + mem
374; AVX512-NEXT:    vmulss {{.*}}(%rip), %xmm1, %xmm1
375; AVX512-NEXT:    vmulss %xmm0, %xmm1, %xmm0
376; AVX512-NEXT:    retq
377  %sqrt = tail call float @llvm.sqrt.f32(float %x)
378  %div = fdiv fast float 1.0, %sqrt
379  ret float %div
380}
381
382define <4 x float> @v4f32_no_estimate(<4 x float> %x) #0 {
383; SSE-LABEL: v4f32_no_estimate:
384; SSE:       # %bb.0:
385; SSE-NEXT:    sqrtps %xmm0, %xmm1
386; SSE-NEXT:    movaps {{.*#+}} xmm0 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]
387; SSE-NEXT:    divps %xmm1, %xmm0
388; SSE-NEXT:    retq
389;
390; AVX1-LABEL: v4f32_no_estimate:
391; AVX1:       # %bb.0:
392; AVX1-NEXT:    vsqrtps %xmm0, %xmm0
393; AVX1-NEXT:    vmovaps {{.*#+}} xmm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]
394; AVX1-NEXT:    vdivps %xmm0, %xmm1, %xmm0
395; AVX1-NEXT:    retq
396;
397; AVX512-LABEL: v4f32_no_estimate:
398; AVX512:       # %bb.0:
399; AVX512-NEXT:    vsqrtps %xmm0, %xmm0
400; AVX512-NEXT:    vbroadcastss {{.*#+}} xmm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]
401; AVX512-NEXT:    vdivps %xmm0, %xmm1, %xmm0
402; AVX512-NEXT:    retq
403  %sqrt = tail call <4 x float> @llvm.sqrt.v4f32(<4 x float> %x)
404  %div = fdiv fast <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, %sqrt
405  ret <4 x float> %div
406}
407
408define <4 x float> @v4f32_estimate(<4 x float> %x) #1 {
409; SSE-LABEL: v4f32_estimate:
410; SSE:       # %bb.0:
411; SSE-NEXT:    rsqrtps %xmm0, %xmm1
412; SSE-NEXT:    mulps %xmm1, %xmm0
413; SSE-NEXT:    mulps %xmm1, %xmm0
414; SSE-NEXT:    addps {{.*}}(%rip), %xmm0
415; SSE-NEXT:    mulps {{.*}}(%rip), %xmm1
416; SSE-NEXT:    mulps %xmm1, %xmm0
417; SSE-NEXT:    retq
418;
419; AVX1-LABEL: v4f32_estimate:
420; AVX1:       # %bb.0:
421; AVX1-NEXT:    vrsqrtps %xmm0, %xmm1
422; AVX1-NEXT:    vmulps %xmm1, %xmm0, %xmm0
423; AVX1-NEXT:    vmulps %xmm1, %xmm0, %xmm0
424; AVX1-NEXT:    vaddps {{.*}}(%rip), %xmm0, %xmm0
425; AVX1-NEXT:    vmulps {{.*}}(%rip), %xmm1, %xmm1
426; AVX1-NEXT:    vmulps %xmm0, %xmm1, %xmm0
427; AVX1-NEXT:    retq
428;
429; AVX512-LABEL: v4f32_estimate:
430; AVX512:       # %bb.0:
431; AVX512-NEXT:    vrsqrtps %xmm0, %xmm1
432; AVX512-NEXT:    vmulps %xmm1, %xmm0, %xmm0
433; AVX512-NEXT:    vbroadcastss {{.*#+}} xmm2 = [-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0]
434; AVX512-NEXT:    vfmadd231ps {{.*#+}} xmm2 = (xmm1 * xmm0) + xmm2
435; AVX512-NEXT:    vbroadcastss {{.*#+}} xmm0 = [-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1]
436; AVX512-NEXT:    vmulps %xmm0, %xmm1, %xmm0
437; AVX512-NEXT:    vmulps %xmm2, %xmm0, %xmm0
438; AVX512-NEXT:    retq
439  %sqrt = tail call <4 x float> @llvm.sqrt.v4f32(<4 x float> %x)
440  %div = fdiv fast <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, %sqrt
441  ret <4 x float> %div
442}
443
444define <8 x float> @v8f32_no_estimate(<8 x float> %x) #0 {
445; SSE-LABEL: v8f32_no_estimate:
446; SSE:       # %bb.0:
447; SSE-NEXT:    sqrtps %xmm1, %xmm2
448; SSE-NEXT:    sqrtps %xmm0, %xmm3
449; SSE-NEXT:    movaps {{.*#+}} xmm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]
450; SSE-NEXT:    movaps %xmm1, %xmm0
451; SSE-NEXT:    divps %xmm3, %xmm0
452; SSE-NEXT:    divps %xmm2, %xmm1
453; SSE-NEXT:    retq
454;
455; AVX1-LABEL: v8f32_no_estimate:
456; AVX1:       # %bb.0:
457; AVX1-NEXT:    vsqrtps %ymm0, %ymm0
458; AVX1-NEXT:    vmovaps {{.*#+}} ymm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0]
459; AVX1-NEXT:    vdivps %ymm0, %ymm1, %ymm0
460; AVX1-NEXT:    retq
461;
462; AVX512-LABEL: v8f32_no_estimate:
463; AVX512:       # %bb.0:
464; AVX512-NEXT:    vsqrtps %ymm0, %ymm0
465; AVX512-NEXT:    vbroadcastss {{.*#+}} ymm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0]
466; AVX512-NEXT:    vdivps %ymm0, %ymm1, %ymm0
467; AVX512-NEXT:    retq
468  %sqrt = tail call <8 x float> @llvm.sqrt.v8f32(<8 x float> %x)
469  %div = fdiv fast <8 x float> <float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0>, %sqrt
470  ret <8 x float> %div
471}
472
473define <8 x float> @v8f32_estimate(<8 x float> %x) #1 {
474; SSE-LABEL: v8f32_estimate:
475; SSE:       # %bb.0:
476; SSE-NEXT:    rsqrtps %xmm0, %xmm2
477; SSE-NEXT:    movaps {{.*#+}} xmm3 = [-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1]
478; SSE-NEXT:    mulps %xmm2, %xmm0
479; SSE-NEXT:    mulps %xmm2, %xmm0
480; SSE-NEXT:    mulps %xmm3, %xmm2
481; SSE-NEXT:    movaps {{.*#+}} xmm4 = [-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0]
482; SSE-NEXT:    addps %xmm4, %xmm0
483; SSE-NEXT:    mulps %xmm2, %xmm0
484; SSE-NEXT:    rsqrtps %xmm1, %xmm2
485; SSE-NEXT:    mulps %xmm2, %xmm3
486; SSE-NEXT:    mulps %xmm2, %xmm1
487; SSE-NEXT:    mulps %xmm2, %xmm1
488; SSE-NEXT:    addps %xmm4, %xmm1
489; SSE-NEXT:    mulps %xmm3, %xmm1
490; SSE-NEXT:    retq
491;
492; AVX1-LABEL: v8f32_estimate:
493; AVX1:       # %bb.0:
494; AVX1-NEXT:    vrsqrtps %ymm0, %ymm1
495; AVX1-NEXT:    vmulps %ymm1, %ymm0, %ymm0
496; AVX1-NEXT:    vmulps %ymm1, %ymm0, %ymm0
497; AVX1-NEXT:    vaddps {{.*}}(%rip), %ymm0, %ymm0
498; AVX1-NEXT:    vmulps {{.*}}(%rip), %ymm1, %ymm1
499; AVX1-NEXT:    vmulps %ymm0, %ymm1, %ymm0
500; AVX1-NEXT:    retq
501;
502; AVX512-LABEL: v8f32_estimate:
503; AVX512:       # %bb.0:
504; AVX512-NEXT:    vrsqrtps %ymm0, %ymm1
505; AVX512-NEXT:    vmulps %ymm1, %ymm0, %ymm0
506; AVX512-NEXT:    vbroadcastss {{.*#+}} ymm2 = [-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0]
507; AVX512-NEXT:    vfmadd231ps {{.*#+}} ymm2 = (ymm1 * ymm0) + ymm2
508; AVX512-NEXT:    vbroadcastss {{.*#+}} ymm0 = [-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1]
509; AVX512-NEXT:    vmulps %ymm0, %ymm1, %ymm0
510; AVX512-NEXT:    vmulps %ymm2, %ymm0, %ymm0
511; AVX512-NEXT:    retq
512  %sqrt = tail call <8 x float> @llvm.sqrt.v8f32(<8 x float> %x)
513  %div = fdiv fast <8 x float> <float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0>, %sqrt
514  ret <8 x float> %div
515}
516
517define <16 x float> @v16f32_no_estimate(<16 x float> %x) #0 {
518; SSE-LABEL: v16f32_no_estimate:
519; SSE:       # %bb.0:
520; SSE-NEXT:    sqrtps %xmm3, %xmm4
521; SSE-NEXT:    sqrtps %xmm2, %xmm5
522; SSE-NEXT:    sqrtps %xmm1, %xmm2
523; SSE-NEXT:    sqrtps %xmm0, %xmm1
524; SSE-NEXT:    movaps {{.*#+}} xmm3 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]
525; SSE-NEXT:    movaps %xmm3, %xmm0
526; SSE-NEXT:    divps %xmm1, %xmm0
527; SSE-NEXT:    movaps %xmm3, %xmm1
528; SSE-NEXT:    divps %xmm2, %xmm1
529; SSE-NEXT:    movaps %xmm3, %xmm2
530; SSE-NEXT:    divps %xmm5, %xmm2
531; SSE-NEXT:    divps %xmm4, %xmm3
532; SSE-NEXT:    retq
533;
534; AVX1-LABEL: v16f32_no_estimate:
535; AVX1:       # %bb.0:
536; AVX1-NEXT:    vsqrtps %ymm1, %ymm1
537; AVX1-NEXT:    vsqrtps %ymm0, %ymm0
538; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0]
539; AVX1-NEXT:    vdivps %ymm0, %ymm2, %ymm0
540; AVX1-NEXT:    vdivps %ymm1, %ymm2, %ymm1
541; AVX1-NEXT:    retq
542;
543; AVX512-LABEL: v16f32_no_estimate:
544; AVX512:       # %bb.0:
545; AVX512-NEXT:    vsqrtps %zmm0, %zmm0
546; AVX512-NEXT:    vbroadcastss {{.*#+}} zmm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0]
547; AVX512-NEXT:    vdivps %zmm0, %zmm1, %zmm0
548; AVX512-NEXT:    retq
549  %sqrt = tail call <16 x float> @llvm.sqrt.v16f32(<16 x float> %x)
550  %div = fdiv fast <16 x float> <float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0>, %sqrt
551  ret <16 x float> %div
552}
553
554define <16 x float> @v16f32_estimate(<16 x float> %x) #1 {
555; SSE-LABEL: v16f32_estimate:
556; SSE:       # %bb.0:
557; SSE-NEXT:    rsqrtps %xmm0, %xmm5
558; SSE-NEXT:    movaps {{.*#+}} xmm4 = [-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1]
559; SSE-NEXT:    mulps %xmm5, %xmm0
560; SSE-NEXT:    mulps %xmm5, %xmm0
561; SSE-NEXT:    movaps %xmm5, %xmm6
562; SSE-NEXT:    mulps %xmm4, %xmm6
563; SSE-NEXT:    movaps {{.*#+}} xmm5 = [-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0]
564; SSE-NEXT:    addps %xmm5, %xmm0
565; SSE-NEXT:    mulps %xmm6, %xmm0
566; SSE-NEXT:    rsqrtps %xmm1, %xmm6
567; SSE-NEXT:    mulps %xmm6, %xmm1
568; SSE-NEXT:    mulps %xmm6, %xmm1
569; SSE-NEXT:    mulps %xmm4, %xmm6
570; SSE-NEXT:    addps %xmm5, %xmm1
571; SSE-NEXT:    mulps %xmm6, %xmm1
572; SSE-NEXT:    rsqrtps %xmm2, %xmm6
573; SSE-NEXT:    mulps %xmm6, %xmm2
574; SSE-NEXT:    mulps %xmm6, %xmm2
575; SSE-NEXT:    mulps %xmm4, %xmm6
576; SSE-NEXT:    addps %xmm5, %xmm2
577; SSE-NEXT:    mulps %xmm6, %xmm2
578; SSE-NEXT:    rsqrtps %xmm3, %xmm6
579; SSE-NEXT:    mulps %xmm6, %xmm4
580; SSE-NEXT:    mulps %xmm6, %xmm3
581; SSE-NEXT:    mulps %xmm6, %xmm3
582; SSE-NEXT:    addps %xmm5, %xmm3
583; SSE-NEXT:    mulps %xmm4, %xmm3
584; SSE-NEXT:    retq
585;
586; AVX1-LABEL: v16f32_estimate:
587; AVX1:       # %bb.0:
588; AVX1-NEXT:    vrsqrtps %ymm0, %ymm2
589; AVX1-NEXT:    vmovaps {{.*#+}} ymm3 = [-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1]
590; AVX1-NEXT:    vmulps %ymm3, %ymm2, %ymm4
591; AVX1-NEXT:    vmulps %ymm2, %ymm0, %ymm0
592; AVX1-NEXT:    vmulps %ymm2, %ymm0, %ymm0
593; AVX1-NEXT:    vmovaps {{.*#+}} ymm2 = [-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0]
594; AVX1-NEXT:    vaddps %ymm2, %ymm0, %ymm0
595; AVX1-NEXT:    vmulps %ymm0, %ymm4, %ymm0
596; AVX1-NEXT:    vrsqrtps %ymm1, %ymm4
597; AVX1-NEXT:    vmulps %ymm3, %ymm4, %ymm3
598; AVX1-NEXT:    vmulps %ymm4, %ymm1, %ymm1
599; AVX1-NEXT:    vmulps %ymm4, %ymm1, %ymm1
600; AVX1-NEXT:    vaddps %ymm2, %ymm1, %ymm1
601; AVX1-NEXT:    vmulps %ymm1, %ymm3, %ymm1
602; AVX1-NEXT:    retq
603;
604; AVX512-LABEL: v16f32_estimate:
605; AVX512:       # %bb.0:
606; AVX512-NEXT:    vrsqrt14ps %zmm0, %zmm1
607; AVX512-NEXT:    vmulps %zmm1, %zmm0, %zmm0
608; AVX512-NEXT:    vfmadd213ps {{.*#+}} zmm0 = (zmm1 * zmm0) + mem
609; AVX512-NEXT:    vmulps {{.*}}(%rip){1to16}, %zmm1, %zmm1
610; AVX512-NEXT:    vmulps %zmm0, %zmm1, %zmm0
611; AVX512-NEXT:    retq
612  %sqrt = tail call <16 x float> @llvm.sqrt.v16f32(<16 x float> %x)
613  %div = fdiv fast <16 x float> <float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0>, %sqrt
614  ret <16 x float> %div
615}
616
617
618attributes #0 = { "unsafe-fp-math"="true" "reciprocal-estimates"="!sqrtf,!vec-sqrtf,!divf,!vec-divf" }
619attributes #1 = { "unsafe-fp-math"="true" "reciprocal-estimates"="sqrt,vec-sqrt" }
620attributes #2 = { nounwind readnone }
621attributes #3 = { "unsafe-fp-math"="true" "reciprocal-estimates"="sqrt,vec-sqrt" "denormal-fp-math"="ieee" }
622attributes #4 = { "unsafe-fp-math"="true" "reciprocal-estimates"="sqrt,vec-sqrt" "denormal-fp-math"="ieee,preserve-sign" }
623