1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx  | FileCheck %s --check-prefix=CHECK --check-prefix=AVX
4
5; It's the extra tests coverage for recip as discussed on D26855.
6
7define float @f32_no_step_2(float %x) #3 {
8; SSE-LABEL: f32_no_step_2:
9; SSE:       # BB#0:
10; SSE-NEXT:    rcpss %xmm0, %xmm0
11; SSE-NEXT:    mulss {{.*}}(%rip), %xmm0
12; SSE-NEXT:    retq
13;
14; AVX-LABEL: f32_no_step_2:
15; AVX:       # BB#0:
16; AVX-NEXT:    vrcpss %xmm0, %xmm0, %xmm0
17; AVX-NEXT:    vmulss {{.*}}(%rip), %xmm0, %xmm0
18; AVX-NEXT:    retq
19  %div = fdiv fast float 1234.0, %x
20  ret float %div
21}
22
23define float @f32_one_step_2(float %x) #1 {
24; SSE-LABEL: f32_one_step_2:
25; SSE:       # BB#0:
26; SSE-NEXT:    rcpss %xmm0, %xmm2
27; SSE-NEXT:    mulss %xmm2, %xmm0
28; SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
29; SSE-NEXT:    subss %xmm0, %xmm1
30; SSE-NEXT:    mulss %xmm2, %xmm1
31; SSE-NEXT:    addss %xmm2, %xmm1
32; SSE-NEXT:    mulss {{.*}}(%rip), %xmm1
33; SSE-NEXT:    movaps %xmm1, %xmm0
34; SSE-NEXT:    retq
35;
36; AVX-LABEL: f32_one_step_2:
37; AVX:       # BB#0:
38; AVX-NEXT:    vrcpss %xmm0, %xmm0, %xmm1
39; AVX-NEXT:    vmulss %xmm1, %xmm0, %xmm0
40; AVX-NEXT:    vmovss {{.*#+}} xmm2 = mem[0],zero,zero,zero
41; AVX-NEXT:    vsubss %xmm0, %xmm2, %xmm0
42; AVX-NEXT:    vmulss %xmm0, %xmm1, %xmm0
43; AVX-NEXT:    vaddss %xmm0, %xmm1, %xmm0
44; AVX-NEXT:    vmulss {{.*}}(%rip), %xmm0, %xmm0
45; AVX-NEXT:    retq
46  %div = fdiv fast float 3456.0, %x
47  ret float %div
48}
49
50define float @f32_two_step_2(float %x) #2 {
51; SSE-LABEL: f32_two_step_2:
52; SSE:       # BB#0:
53; SSE-NEXT:    rcpss %xmm0, %xmm2
54; SSE-NEXT:    movaps %xmm0, %xmm3
55; SSE-NEXT:    mulss %xmm2, %xmm3
56; SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
57; SSE-NEXT:    movaps %xmm1, %xmm4
58; SSE-NEXT:    subss %xmm3, %xmm4
59; SSE-NEXT:    mulss %xmm2, %xmm4
60; SSE-NEXT:    addss %xmm2, %xmm4
61; SSE-NEXT:    mulss %xmm4, %xmm0
62; SSE-NEXT:    subss %xmm0, %xmm1
63; SSE-NEXT:    mulss %xmm4, %xmm1
64; SSE-NEXT:    addss %xmm4, %xmm1
65; SSE-NEXT:    mulss {{.*}}(%rip), %xmm1
66; SSE-NEXT:    movaps %xmm1, %xmm0
67; SSE-NEXT:    retq
68;
69; AVX-LABEL: f32_two_step_2:
70; AVX:       # BB#0:
71; AVX-NEXT:    vrcpss %xmm0, %xmm0, %xmm1
72; AVX-NEXT:    vmulss %xmm1, %xmm0, %xmm2
73; AVX-NEXT:    vmovss {{.*#+}} xmm3 = mem[0],zero,zero,zero
74; AVX-NEXT:    vsubss %xmm2, %xmm3, %xmm2
75; AVX-NEXT:    vmulss %xmm2, %xmm1, %xmm2
76; AVX-NEXT:    vaddss %xmm2, %xmm1, %xmm1
77; AVX-NEXT:    vmulss %xmm1, %xmm0, %xmm0
78; AVX-NEXT:    vsubss %xmm0, %xmm3, %xmm0
79; AVX-NEXT:    vmulss %xmm0, %xmm1, %xmm0
80; AVX-NEXT:    vaddss %xmm0, %xmm1, %xmm0
81; AVX-NEXT:    vmulss {{.*}}(%rip), %xmm0, %xmm0
82; AVX-NEXT:    retq
83  %div = fdiv fast float 6789.0, %x
84  ret float %div
85}
86
87define <4 x float> @v4f32_one_step2(<4 x float> %x) #1 {
88; SSE-LABEL: v4f32_one_step2:
89; SSE:       # BB#0:
90; SSE-NEXT:    rcpps %xmm0, %xmm2
91; SSE-NEXT:    mulps %xmm2, %xmm0
92; SSE-NEXT:    movaps {{.*#+}} xmm1 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00]
93; SSE-NEXT:    subps %xmm0, %xmm1
94; SSE-NEXT:    mulps %xmm2, %xmm1
95; SSE-NEXT:    addps %xmm2, %xmm1
96; SSE-NEXT:    mulps {{.*}}(%rip), %xmm1
97; SSE-NEXT:    movaps %xmm1, %xmm0
98; SSE-NEXT:    retq
99;
100; AVX-LABEL: v4f32_one_step2:
101; AVX:       # BB#0:
102; AVX-NEXT:    vrcpps %xmm0, %xmm1
103; AVX-NEXT:    vmulps %xmm1, %xmm0, %xmm0
104; AVX-NEXT:    vmovaps {{.*#+}} xmm2 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00]
105; AVX-NEXT:    vsubps %xmm0, %xmm2, %xmm0
106; AVX-NEXT:    vmulps %xmm0, %xmm1, %xmm0
107; AVX-NEXT:    vaddps %xmm0, %xmm1, %xmm0
108; AVX-NEXT:    vmulps {{.*}}(%rip), %xmm0, %xmm0
109; AVX-NEXT:    retq
110  %div = fdiv fast <4 x float> <float 1.0, float 2.0, float 3.0, float 4.0>, %x
111  ret <4 x float> %div
112}
113
114define <4 x float> @v4f32_two_step2(<4 x float> %x) #2 {
115; SSE-LABEL: v4f32_two_step2:
116; SSE:       # BB#0:
117; SSE-NEXT:    rcpps %xmm0, %xmm2
118; SSE-NEXT:    movaps %xmm0, %xmm3
119; SSE-NEXT:    mulps %xmm2, %xmm3
120; SSE-NEXT:    movaps {{.*#+}} xmm1 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00]
121; SSE-NEXT:    movaps %xmm1, %xmm4
122; SSE-NEXT:    subps %xmm3, %xmm4
123; SSE-NEXT:    mulps %xmm2, %xmm4
124; SSE-NEXT:    addps %xmm2, %xmm4
125; SSE-NEXT:    mulps %xmm4, %xmm0
126; SSE-NEXT:    subps %xmm0, %xmm1
127; SSE-NEXT:    mulps %xmm4, %xmm1
128; SSE-NEXT:    addps %xmm4, %xmm1
129; SSE-NEXT:    mulps {{.*}}(%rip), %xmm1
130; SSE-NEXT:    movaps %xmm1, %xmm0
131; SSE-NEXT:    retq
132;
133; AVX-LABEL: v4f32_two_step2:
134; AVX:       # BB#0:
135; AVX-NEXT:    vrcpps %xmm0, %xmm1
136; AVX-NEXT:    vmulps %xmm1, %xmm0, %xmm2
137; AVX-NEXT:    vmovaps {{.*#+}} xmm3 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00]
138; AVX-NEXT:    vsubps %xmm2, %xmm3, %xmm2
139; AVX-NEXT:    vmulps %xmm2, %xmm1, %xmm2
140; AVX-NEXT:    vaddps %xmm2, %xmm1, %xmm1
141; AVX-NEXT:    vmulps %xmm1, %xmm0, %xmm0
142; AVX-NEXT:    vsubps %xmm0, %xmm3, %xmm0
143; AVX-NEXT:    vmulps %xmm0, %xmm1, %xmm0
144; AVX-NEXT:    vaddps %xmm0, %xmm1, %xmm0
145; AVX-NEXT:    vmulps {{.*}}(%rip), %xmm0, %xmm0
146; AVX-NEXT:    retq
147  %div = fdiv fast <4 x float> <float 1.0, float 2.0, float 3.0, float 4.0>, %x
148  ret <4 x float> %div
149}
150
151define <8 x float> @v8f32_one_step2(<8 x float> %x) #1 {
152; SSE-LABEL: v8f32_one_step2:
153; SSE:       # BB#0:
154; SSE-NEXT:    rcpps %xmm1, %xmm4
155; SSE-NEXT:    mulps %xmm4, %xmm1
156; SSE-NEXT:    movaps {{.*#+}} xmm2 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00]
157; SSE-NEXT:    movaps %xmm2, %xmm3
158; SSE-NEXT:    subps %xmm1, %xmm3
159; SSE-NEXT:    mulps %xmm4, %xmm3
160; SSE-NEXT:    addps %xmm4, %xmm3
161; SSE-NEXT:    rcpps %xmm0, %xmm1
162; SSE-NEXT:    mulps %xmm1, %xmm0
163; SSE-NEXT:    subps %xmm0, %xmm2
164; SSE-NEXT:    mulps %xmm1, %xmm2
165; SSE-NEXT:    addps %xmm1, %xmm2
166; SSE-NEXT:    mulps {{.*}}(%rip), %xmm2
167; SSE-NEXT:    mulps {{.*}}(%rip), %xmm3
168; SSE-NEXT:    movaps %xmm2, %xmm0
169; SSE-NEXT:    movaps %xmm3, %xmm1
170; SSE-NEXT:    retq
171;
172; AVX-LABEL: v8f32_one_step2:
173; AVX:       # BB#0:
174; AVX-NEXT:    vrcpps %ymm0, %ymm1
175; AVX-NEXT:    vmulps %ymm1, %ymm0, %ymm0
176; AVX-NEXT:    vmovaps {{.*#+}} ymm2 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00]
177; AVX-NEXT:    vsubps %ymm0, %ymm2, %ymm0
178; AVX-NEXT:    vmulps %ymm0, %ymm1, %ymm0
179; AVX-NEXT:    vaddps %ymm0, %ymm1, %ymm0
180; AVX-NEXT:    vmulps {{.*}}(%rip), %ymm0, %ymm0
181; AVX-NEXT:    retq
182  %div = fdiv fast <8 x float> <float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, float 6.0, float 7.0, float 8.0>, %x
183  ret <8 x float> %div
184}
185
186define <8 x float> @v8f32_two_step2(<8 x float> %x) #2 {
187; SSE-LABEL: v8f32_two_step2:
188; SSE:       # BB#0:
189; SSE-NEXT:    movaps %xmm0, %xmm2
190; SSE-NEXT:    rcpps %xmm1, %xmm3
191; SSE-NEXT:    movaps %xmm1, %xmm4
192; SSE-NEXT:    mulps %xmm3, %xmm4
193; SSE-NEXT:    movaps {{.*#+}} xmm0 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00]
194; SSE-NEXT:    movaps %xmm0, %xmm5
195; SSE-NEXT:    subps %xmm4, %xmm5
196; SSE-NEXT:    mulps %xmm3, %xmm5
197; SSE-NEXT:    addps %xmm3, %xmm5
198; SSE-NEXT:    mulps %xmm5, %xmm1
199; SSE-NEXT:    movaps %xmm0, %xmm3
200; SSE-NEXT:    subps %xmm1, %xmm3
201; SSE-NEXT:    mulps %xmm5, %xmm3
202; SSE-NEXT:    addps %xmm5, %xmm3
203; SSE-NEXT:    rcpps %xmm2, %xmm1
204; SSE-NEXT:    movaps %xmm2, %xmm4
205; SSE-NEXT:    mulps %xmm1, %xmm4
206; SSE-NEXT:    movaps %xmm0, %xmm5
207; SSE-NEXT:    subps %xmm4, %xmm5
208; SSE-NEXT:    mulps %xmm1, %xmm5
209; SSE-NEXT:    addps %xmm1, %xmm5
210; SSE-NEXT:    mulps %xmm5, %xmm2
211; SSE-NEXT:    subps %xmm2, %xmm0
212; SSE-NEXT:    mulps %xmm5, %xmm0
213; SSE-NEXT:    addps %xmm5, %xmm0
214; SSE-NEXT:    mulps {{.*}}(%rip), %xmm0
215; SSE-NEXT:    mulps {{.*}}(%rip), %xmm3
216; SSE-NEXT:    movaps %xmm3, %xmm1
217; SSE-NEXT:    retq
218;
219; AVX-LABEL: v8f32_two_step2:
220; AVX:       # BB#0:
221; AVX-NEXT:    vrcpps %ymm0, %ymm1
222; AVX-NEXT:    vmulps %ymm1, %ymm0, %ymm2
223; AVX-NEXT:    vmovaps {{.*#+}} ymm3 = [1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00,1.000000e+00]
224; AVX-NEXT:    vsubps %ymm2, %ymm3, %ymm2
225; AVX-NEXT:    vmulps %ymm2, %ymm1, %ymm2
226; AVX-NEXT:    vaddps %ymm2, %ymm1, %ymm1
227; AVX-NEXT:    vmulps %ymm1, %ymm0, %ymm0
228; AVX-NEXT:    vsubps %ymm0, %ymm3, %ymm0
229; AVX-NEXT:    vmulps %ymm0, %ymm1, %ymm0
230; AVX-NEXT:    vaddps %ymm0, %ymm1, %ymm0
231; AVX-NEXT:    vmulps {{.*}}(%rip), %ymm0, %ymm0
232; AVX-NEXT:    retq
233  %div = fdiv fast <8 x float> <float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, float 6.0, float 7.0, float 8.0>, %x
234  ret <8 x float> %div
235}
236
237define <8 x float> @v8f32_no_step(<8 x float> %x) #3 {
238; SSE-LABEL: v8f32_no_step:
239; SSE:       # BB#0:
240; SSE-NEXT:    rcpps %xmm0, %xmm0
241; SSE-NEXT:    rcpps %xmm1, %xmm1
242; SSE-NEXT:    retq
243;
244; AVX-LABEL: v8f32_no_step:
245; AVX:       # BB#0:
246; AVX-NEXT:    vrcpps %ymm0, %ymm0
247; AVX-NEXT:    retq
248  %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>, %x
249  ret <8 x float> %div
250}
251
252define <8 x float> @v8f32_no_step2(<8 x float> %x) #3 {
253; SSE-LABEL: v8f32_no_step2:
254; SSE:       # BB#0:
255; SSE-NEXT:    rcpps %xmm1, %xmm1
256; SSE-NEXT:    rcpps %xmm0, %xmm0
257; SSE-NEXT:    mulps {{.*}}(%rip), %xmm0
258; SSE-NEXT:    mulps {{.*}}(%rip), %xmm1
259; SSE-NEXT:    retq
260;
261; AVX-LABEL: v8f32_no_step2:
262; AVX:       # BB#0:
263; AVX-NEXT:    vrcpps %ymm0, %ymm0
264; AVX-NEXT:    vmulps {{.*}}(%rip), %ymm0, %ymm0
265; AVX-NEXT:    retq
266  %div = fdiv fast <8 x float> <float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, float 6.0, float 7.0, float 8.0>, %x
267  ret <8 x float> %div
268}
269
270attributes #0 = { "unsafe-fp-math"="true" "reciprocal-estimates"="!divf,!vec-divf" }
271attributes #1 = { "unsafe-fp-math"="true" "reciprocal-estimates"="divf,vec-divf" }
272attributes #2 = { "unsafe-fp-math"="true" "reciprocal-estimates"="divf:2,vec-divf:2" }
273attributes #3 = { "unsafe-fp-math"="true" "reciprocal-estimates"="divf:0,vec-divf:0" }
274
275