1; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -enable-unsafe-fp-math -mattr=-vsx | FileCheck %s
2; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -enable-unsafe-fp-math -mattr=-vsx -recip=sqrtf:0,sqrtd:0 | FileCheck %s -check-prefix=CHECK-NONR
3; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -mattr=-vsx | FileCheck -check-prefix=CHECK-SAFE %s
4target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
5target triple = "powerpc64-unknown-linux-gnu"
6
7declare double @llvm.sqrt.f64(double)
8declare float @llvm.sqrt.f32(float)
9declare <4 x float> @llvm.sqrt.v4f32(<4 x float>)
10
11define double @foo(double %a, double %b) nounwind {
12  %x = call double @llvm.sqrt.f64(double %b)
13  %r = fdiv double %a, %x
14  ret double %r
15
16; CHECK: @foo
17; CHECK-DAG: frsqrte
18; CHECK-DAG: fnmsub
19; CHECK: fmul
20; CHECK-NEXT: fmadd
21; CHECK-NEXT: fmul
22; CHECK-NEXT: fmul
23; CHECK-NEXT: fmadd
24; CHECK-NEXT: fmul
25; CHECK-NEXT: fmul
26; CHECK: blr
27
28; CHECK-NONR: @foo
29; CHECK-NONR: frsqrte
30; CHECK-NONR-NOT: fmadd
31; CHECK-NONR: fmul
32; CHECK-NONR-NOT: fmadd
33; CHECK-NONR: blr
34
35; CHECK-SAFE: @foo
36; CHECK-SAFE: fsqrt
37; CHECK-SAFE: fdiv
38; CHECK-SAFE: blr
39}
40
41define double @foof(double %a, float %b) nounwind {
42  %x = call float @llvm.sqrt.f32(float %b)
43  %y = fpext float %x to double
44  %r = fdiv double %a, %y
45  ret double %r
46
47; CHECK: @foof
48; CHECK-DAG: frsqrtes
49; CHECK-DAG: fnmsubs
50; CHECK: fmuls
51; CHECK-NEXT: fmadds
52; CHECK-NEXT: fmuls
53; CHECK-NEXT: fmul
54; CHECK-NEXT: blr
55
56; CHECK-SAFE: @foof
57; CHECK-SAFE: fsqrts
58; CHECK-SAFE: fdiv
59; CHECK-SAFE: blr
60}
61
62define float @food(float %a, double %b) nounwind {
63  %x = call double @llvm.sqrt.f64(double %b)
64  %y = fptrunc double %x to float
65  %r = fdiv float %a, %y
66  ret float %r
67
68; CHECK: @foo
69; CHECK-DAG: frsqrte
70; CHECK-DAG: fnmsub
71; CHECK: fmul
72; CHECK-NEXT: fmadd
73; CHECK-NEXT: fmul
74; CHECK-NEXT: fmul
75; CHECK-NEXT: fmadd
76; CHECK-NEXT: fmul
77; CHECK-NEXT: frsp
78; CHECK-NEXT: fmuls
79; CHECK-NEXT: blr
80
81; CHECK-SAFE: @foo
82; CHECK-SAFE: fsqrt
83; CHECK-SAFE: fdivs
84; CHECK-SAFE: blr
85}
86
87define float @goo(float %a, float %b) nounwind {
88  %x = call float @llvm.sqrt.f32(float %b)
89  %r = fdiv float %a, %x
90  ret float %r
91
92; CHECK: @goo
93; CHECK-DAG: frsqrtes
94; CHECK-DAG: fnmsubs
95; CHECK: fmuls
96; CHECK-NEXT: fmadds
97; CHECK-NEXT: fmuls
98; CHECK-NEXT: fmuls
99; CHECK-NEXT: blr
100
101; CHECK-NONR: @goo
102; CHECK-NONR: frsqrtes
103; CHECK-NONR-NOT: fmadds
104; CHECK-NONR: fmuls
105; CHECK-NONR-NOT: fmadds
106; CHECK-NONR: blr
107
108; CHECK-SAFE: @goo
109; CHECK-SAFE: fsqrts
110; CHECK-SAFE: fdivs
111; CHECK-SAFE: blr
112}
113
114; Recognize that this is rsqrt(a) * rcp(b) * c,
115; not 1 / ( 1 / sqrt(a)) * rcp(b) * c.
116define float @rsqrt_fmul(float %a, float %b, float %c) {
117  %x = call float @llvm.sqrt.f32(float %a)
118  %y = fmul float %x, %b
119  %z = fdiv float %c, %y
120  ret float %z
121
122; CHECK: @rsqrt_fmul
123; CHECK-DAG: frsqrtes
124; CHECK-DAG: fres
125; CHECK-DAG: fnmsubs
126; CHECK-DAG: fmuls
127; CHECK-DAG: fnmsubs
128; CHECK-DAG: fmadds
129; CHECK-DAG: fmadds
130; CHECK: fmuls
131; CHECK-NEXT: fmuls
132; CHECK-NEXT: fmuls
133; CHECK-NEXT: blr
134
135; CHECK-SAFE: @rsqrt_fmul
136; CHECK-SAFE: fsqrts
137; CHECK-SAFE: fmuls
138; CHECK-SAFE: fdivs
139; CHECK-SAFE: blr
140}
141
142define <4 x float> @hoo(<4 x float> %a, <4 x float> %b) nounwind {
143  %x = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %b)
144  %r = fdiv <4 x float> %a, %x
145  ret <4 x float> %r
146
147; CHECK: @hoo
148; CHECK: vrsqrtefp
149
150; CHECK-SAFE: @hoo
151; CHECK-SAFE-NOT: vrsqrtefp
152; CHECK-SAFE: blr
153}
154
155define double @foo2(double %a, double %b) nounwind {
156  %r = fdiv double %a, %b
157  ret double %r
158
159; CHECK: @foo2
160; CHECK-DAG: fre
161; CHECK-DAG: fnmsub
162; CHECK: fmadd
163; CHECK-NEXT: fnmsub
164; CHECK-NEXT: fmadd
165; CHECK-NEXT: fmul
166; CHECK-NEXT: blr
167
168; CHECK-SAFE: @foo2
169; CHECK-SAFE: fdiv
170; CHECK-SAFE: blr
171}
172
173define float @goo2(float %a, float %b) nounwind {
174  %r = fdiv float %a, %b
175  ret float %r
176
177; CHECK: @goo2
178; CHECK-DAG: fres
179; CHECK-DAG: fnmsubs
180; CHECK: fmadds
181; CHECK-NEXT: fmuls
182; CHECK-NEXT: blr
183
184; CHECK-SAFE: @goo2
185; CHECK-SAFE: fdivs
186; CHECK-SAFE: blr
187}
188
189define <4 x float> @hoo2(<4 x float> %a, <4 x float> %b) nounwind {
190  %r = fdiv <4 x float> %a, %b
191  ret <4 x float> %r
192
193; CHECK: @hoo2
194; CHECK: vrefp
195
196; CHECK-SAFE: @hoo2
197; CHECK-SAFE-NOT: vrefp
198; CHECK-SAFE: blr
199}
200
201define double @foo3(double %a) nounwind {
202  %r = call double @llvm.sqrt.f64(double %a)
203  ret double %r
204
205; CHECK: @foo3
206; CHECK: fcmpu
207; CHECK-DAG: frsqrte
208; CHECK-DAG: fnmsub
209; CHECK: fmul
210; CHECK-NEXT: fmadd
211; CHECK-NEXT: fmul
212; CHECK-NEXT: fmul
213; CHECK-NEXT: fmadd
214; CHECK-NEXT: fmul
215; CHECK-NEXT: fmul
216; CHECK: blr
217
218; CHECK-SAFE: @foo3
219; CHECK-SAFE: fsqrt
220; CHECK-SAFE: blr
221}
222
223define float @goo3(float %a) nounwind {
224  %r = call float @llvm.sqrt.f32(float %a)
225  ret float %r
226
227; CHECK: @goo3
228; CHECK: fcmpu
229; CHECK-DAG: frsqrtes
230; CHECK-DAG: fnmsubs
231; CHECK: fmuls
232; CHECK-NEXT: fmadds
233; CHECK-NEXT: fmuls
234; CHECK-NEXT: fmuls
235; CHECK: blr
236
237; CHECK-SAFE: @goo3
238; CHECK-SAFE: fsqrts
239; CHECK-SAFE: blr
240}
241
242define <4 x float> @hoo3(<4 x float> %a) nounwind {
243  %r = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %a)
244  ret <4 x float> %r
245
246; CHECK: @hoo3
247; CHECK: vrsqrtefp
248; CHECK-DAG: vcmpeqfp
249
250; CHECK-SAFE: @hoo3
251; CHECK-SAFE-NOT: vrsqrtefp
252; CHECK-SAFE: blr
253}
254
255