1; RUN: llc < %s -mtriple=aarch64-unknown-linux-gnu -mattr=+neon,-use-reciprocal-square-root | FileCheck %s --check-prefix=FAULT
2; RUN: llc < %s -mtriple=aarch64-unknown-linux-gnu -mattr=+neon,+use-reciprocal-square-root | FileCheck %s
3
4declare float @llvm.sqrt.f32(float) #0
5declare <2 x float> @llvm.sqrt.v2f32(<2 x float>) #0
6declare <4 x float> @llvm.sqrt.v4f32(<4 x float>) #0
7declare <8 x float> @llvm.sqrt.v8f32(<8 x float>) #0
8declare double @llvm.sqrt.f64(double) #0
9declare <2 x double> @llvm.sqrt.v2f64(<2 x double>) #0
10declare <4 x double> @llvm.sqrt.v4f64(<4 x double>) #0
11
12define float @fsqrt(float %a) #0 {
13  %1 = tail call fast float @llvm.sqrt.f32(float %a)
14  ret float %1
15
16; FAULT-LABEL: fsqrt:
17; FAULT-NEXT: BB#0
18; FAULT-NEXT: fsqrt
19
20; CHECK-LABEL: fsqrt:
21; CHECK-NEXT: BB#0
22; CHECK-NEXT: frsqrte [[RA:s[0-7]]]
23; CHECK-NEXT: fmul [[RB:s[0-7]]], [[RA]], [[RA]]
24; CHECK-NEXT: frsqrts {{s[0-7](, s[0-7])?}}, [[RB]]
25; CHECK: frsqrts {{s[0-7]}}, {{s[0-7]}}, {{s[0-7]}}
26; CHECK-NOT: frsqrts {{s[0-7]}}, {{s[0-7]}}, {{s[0-7]}}
27; CHECK: fcmp {{s[0-7]}}, #0
28}
29
30define <2 x float> @f2sqrt(<2 x float> %a) #0 {
31  %1 = tail call fast <2 x float> @llvm.sqrt.v2f32(<2 x float> %a)
32  ret <2 x float> %1
33
34; FAULT-LABEL: f2sqrt:
35; FAULT-NEXT: BB#0
36; FAULT-NEXT: fsqrt
37
38; CHECK-LABEL: f2sqrt:
39; CHECK-NEXT: BB#0
40; CHECK-NEXT: frsqrte [[RA:v[0-7]\.2s]]
41; CHECK-NEXT: fmul [[RB:v[0-7]\.2s]], [[RA]], [[RA]]
42; CHECK-NEXT: frsqrts {{v[0-7]\.2s(, v[0-7]\.2s)?}}, [[RB]]
43; CHECK: frsqrts {{v[0-7]\.2s}}, {{v[0-7]\.2s}}, {{v[0-7]\.2s}}
44; CHECK-NOT: frsqrts {{v[0-7]\.2s}}, {{v[0-7]\.2s}}, {{v[0-7]\.2s}}
45; CHECK: fcmeq {{v[0-7]\.2s}}, {{v[0-7]\.2s}}, #0
46}
47
48define <4 x float> @f4sqrt(<4 x float> %a) #0 {
49  %1 = tail call fast <4 x float> @llvm.sqrt.v4f32(<4 x float> %a)
50  ret <4 x float> %1
51
52; FAULT-LABEL: f4sqrt:
53; FAULT-NEXT: BB#0
54; FAULT-NEXT: fsqrt
55
56; CHECK-LABEL: f4sqrt:
57; CHECK-NEXT: BB#0
58; CHECK-NEXT: frsqrte [[RA:v[0-7]\.4s]]
59; CHECK-NEXT: fmul [[RB:v[0-7]\.4s]], [[RA]], [[RA]]
60; CHECK-NEXT: frsqrts {{v[0-7]\.4s(, v[0-7]\.4s)?}}, [[RB]]
61; CHECK: frsqrts {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, {{v[0-7]\.4s}}
62; CHECK-NOT: frsqrts {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, {{v[0-7]\.4s}}
63; CHECK: fcmeq {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, #0
64}
65
66define <8 x float> @f8sqrt(<8 x float> %a) #0 {
67  %1 = tail call fast <8 x float> @llvm.sqrt.v8f32(<8 x float> %a)
68  ret <8 x float> %1
69
70; FAULT-LABEL: f8sqrt:
71; FAULT-NEXT: BB#0
72; FAULT-NEXT: fsqrt
73; FAULT-NEXT: fsqrt
74
75; CHECK-LABEL: f8sqrt:
76; CHECK-NEXT: BB#0
77; CHECK-NEXT: frsqrte [[RA:v[0-7]\.4s]]
78; CHECK-NEXT: fmul [[RB:v[0-7]\.4s]], [[RA]], [[RA]]
79; CHECK-NEXT: frsqrts {{v[0-7]\.4s(, v[0-7]\.4s)?}}, [[RB]]
80; CHECK: frsqrts {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, {{v[0-7]\.4s}}
81; CHECK: fcmeq {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, #0
82; CHECK: frsqrte [[RC:v[0-7]\.4s]]
83; CHECK-NEXT: fmul [[RD:v[0-7]\.4s]], [[RC]], [[RC]]
84; CHECK-NEXT: frsqrts {{v[0-7]\.4s(, v[0-7]\.4s)?}}, [[RD]]
85; CHECK: frsqrts {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, {{v[0-7]\.4s}}
86; CHECK-NOT: frsqrts {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, {{v[0-7]\.4s}}
87; CHECK: fcmeq {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, #0
88}
89
90define double @dsqrt(double %a) #0 {
91  %1 = tail call fast double @llvm.sqrt.f64(double %a)
92  ret double %1
93
94; FAULT-LABEL: dsqrt:
95; FAULT-NEXT: BB#0
96; FAULT-NEXT: fsqrt
97
98; CHECK-LABEL: dsqrt:
99; CHECK-NEXT: BB#0
100; CHECK-NEXT: frsqrte [[RA:d[0-7]]]
101; CHECK-NEXT: fmul [[RB:d[0-7]]], [[RA]], [[RA]]
102; CHECK-NEXT: frsqrts {{d[0-7](, d[0-7])?}}, [[RB]]
103; CHECK: frsqrts {{d[0-7]}}, {{d[0-7]}}, {{d[0-7]}}
104; CHECK: frsqrts {{d[0-7]}}, {{d[0-7]}}, {{d[0-7]}}
105; CHECK-NOT: frsqrts {{d[0-7]}}, {{d[0-7]}}, {{d[0-7]}}
106; CHECK: fcmp {{d[0-7]}}, #0
107}
108
109define <2 x double> @d2sqrt(<2 x double> %a) #0 {
110  %1 = tail call fast <2 x double> @llvm.sqrt.v2f64(<2 x double> %a)
111  ret <2 x double> %1
112
113; FAULT-LABEL: d2sqrt:
114; FAULT-NEXT: BB#0
115; FAULT-NEXT: fsqrt
116
117; CHECK-LABEL: d2sqrt:
118; CHECK-NEXT: BB#0
119; CHECK-NEXT: frsqrte [[RA:v[0-7]\.2d]]
120; CHECK-NEXT: fmul [[RB:v[0-7]\.2d]], [[RA]], [[RA]]
121; CHECK-NEXT: frsqrts {{v[0-7]\.2d(, v[0-7]\.2d)?}}, [[RB]]
122; CHECK: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
123; CHECK: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
124; CHECK-NOT: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
125; CHECK: fcmeq {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, #0
126}
127
128define <4 x double> @d4sqrt(<4 x double> %a) #0 {
129  %1 = tail call fast <4 x double> @llvm.sqrt.v4f64(<4 x double> %a)
130  ret <4 x double> %1
131
132; FAULT-LABEL: d4sqrt:
133; FAULT-NEXT: BB#0
134; FAULT-NEXT: fsqrt
135; FAULT-NEXT: fsqrt
136
137; CHECK-LABEL: d4sqrt:
138; CHECK-NEXT: BB#0
139; CHECK-NEXT: frsqrte [[RA:v[0-7]\.2d]]
140; CHECK-NEXT: fmul [[RB:v[0-7]\.2d]], [[RA]], [[RA]]
141; CHECK-NEXT: frsqrts {{v[0-7]\.2d(, v[0-7]\.2d)?}}, [[RB]]
142; CHECK: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
143; CHECK: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
144; CHECK-NOT: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
145; CHECK: fcmeq {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, #0
146; CHECK: frsqrte [[RC:v[0-7]\.2d]]
147; CHECK-NEXT: fmul [[RD:v[0-7]\.2d]], [[RC]], [[RC]]
148; CHECK-NEXT: frsqrts {{v[0-7]\.2d(, v[0-7]\.2d)?}}, [[RD]]
149; CHECK: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
150; CHECK: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
151; CHECK-NOT: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
152; CHECK: fcmeq {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, #0
153}
154
155define float @frsqrt(float %a) #0 {
156  %1 = tail call fast float @llvm.sqrt.f32(float %a)
157  %2 = fdiv fast float 1.000000e+00, %1
158  ret float %2
159
160; FAULT-LABEL: frsqrt:
161; FAULT-NEXT: BB#0
162; FAULT-NEXT: fsqrt
163
164; CHECK-LABEL: frsqrt:
165; CHECK-NEXT: BB#0
166; CHECK-NEXT: frsqrte [[RA:s[0-7]]]
167; CHECK-NEXT: fmul [[RB:s[0-7]]], [[RA]], [[RA]]
168; CHECK-NEXT: frsqrts {{s[0-7](, s[0-7])?}}, [[RB]]
169; CHECK: frsqrts {{s[0-7]}}, {{s[0-7]}}, {{s[0-7]}}
170; CHECK-NOT: frsqrts {{s[0-7]}}, {{s[0-7]}}, {{s[0-7]}}
171; CHECK-NOT: fcmp {{s[0-7]}}, #0
172}
173
174define <2 x float> @f2rsqrt(<2 x float> %a) #0 {
175  %1 = tail call fast <2 x float> @llvm.sqrt.v2f32(<2 x float> %a)
176  %2 = fdiv fast <2 x float> <float 1.000000e+00, float 1.000000e+00>, %1
177  ret <2 x float> %2
178
179; FAULT-LABEL: f2rsqrt:
180; FAULT-NEXT: BB#0
181; FAULT-NEXT: fsqrt
182
183; CHECK-LABEL: f2rsqrt:
184; CHECK-NEXT: BB#0
185; CHECK-NEXT: frsqrte [[RA:v[0-7]\.2s]]
186; CHECK-NEXT: fmul [[RB:v[0-7]\.2s]], [[RA]], [[RA]]
187; CHECK-NEXT: frsqrts {{v[0-7]\.2s(, v[0-7]\.2s)?}}, [[RB]]
188; CHECK: frsqrts {{v[0-7]\.2s}}, {{v[0-7]\.2s}}, {{v[0-7]\.2s}}
189; CHECK-NOT: frsqrts {{v[0-7]\.2s}}, {{v[0-7]\.2s}}, {{v[0-7]\.2s}}
190; CHECK-NOT: fcmeq {{v[0-7]\.2s}}, {{v[0-7]\.2s}}, #0
191}
192
193define <4 x float> @f4rsqrt(<4 x float> %a) #0 {
194  %1 = tail call fast <4 x float> @llvm.sqrt.v4f32(<4 x float> %a)
195  %2 = fdiv fast <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, %1
196  ret <4 x float> %2
197
198; FAULT-LABEL: f4rsqrt:
199; FAULT-NEXT: BB#0
200; FAULT-NEXT: fsqrt
201
202; CHECK-LABEL: f4rsqrt:
203; CHECK-NEXT: BB#0
204; CHECK-NEXT: frsqrte [[RA:v[0-7]\.4s]]
205; CHECK-NEXT: fmul [[RB:v[0-7]\.4s]], [[RA]], [[RA]]
206; CHECK-NEXT: frsqrts {{v[0-7]\.4s(, v[0-7]\.4s)?}}, [[RB]]
207; CHECK: frsqrts {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, {{v[0-7]\.4s}}
208; CHECK-NOT: frsqrts {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, {{v[0-7]\.4s}}
209; CHECK-NOT: fcmeq {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, #0
210}
211
212define <8 x float> @f8rsqrt(<8 x float> %a) #0 {
213  %1 = tail call fast <8 x float> @llvm.sqrt.v8f32(<8 x float> %a)
214  %2 = fdiv fast <8 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, %1
215  ret <8 x float> %2
216
217; FAULT-LABEL: f8rsqrt:
218; FAULT-NEXT: BB#0
219; FAULT-NEXT: fsqrt
220; FAULT-NEXT: fsqrt
221
222; CHECK-LABEL: f8rsqrt:
223; CHECK-NEXT: BB#0
224; CHECK-NEXT: frsqrte [[RA:v[0-7]\.4s]]
225; CHECK: fmul [[RB:v[0-7]\.4s]], [[RA]], [[RA]]
226; CHECK: frsqrts {{v[0-7]\.4s(, v[0-7]\.4s)?}}, [[RB]]
227; CHECK: frsqrts {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, {{v[0-7]\.4s}}
228; CHECK: frsqrts {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, {{v[0-7]\.4s}}
229; CHECK: frsqrts {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, {{v[0-7]\.4s}}
230; CHECK-NOT: frsqrts {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, {{v[0-7]\.4s}}
231; CHECK-NOT: fcmeq {{v[0-7]\.4s}}, {{v[0-7]\.4s}}, #0
232}
233
234define double @drsqrt(double %a) #0 {
235  %1 = tail call fast double @llvm.sqrt.f64(double %a)
236  %2 = fdiv fast double 1.000000e+00, %1
237  ret double %2
238
239; FAULT-LABEL: drsqrt:
240; FAULT-NEXT: BB#0
241; FAULT-NEXT: fsqrt
242
243; CHECK-LABEL: drsqrt:
244; CHECK-NEXT: BB#0
245; CHECK-NEXT: frsqrte [[RA:d[0-7]]]
246; CHECK-NEXT: fmul [[RB:d[0-7]]], [[RA]], [[RA]]
247; CHECK-NEXT: frsqrts {{d[0-7](, d[0-7])?}}, [[RB]]
248; CHECK: frsqrts {{d[0-7]}}, {{d[0-7]}}, {{d[0-7]}}
249; CHECK: frsqrts {{d[0-7]}}, {{d[0-7]}}, {{d[0-7]}}
250; CHECK-NOT: frsqrts {{d[0-7]}}, {{d[0-7]}}, {{d[0-7]}}
251; CHECK-NOT: fcmp d0, #0
252}
253
254define <2 x double> @d2rsqrt(<2 x double> %a) #0 {
255  %1 = tail call fast <2 x double> @llvm.sqrt.v2f64(<2 x double> %a)
256  %2 = fdiv fast <2 x double> <double 1.000000e+00, double 1.000000e+00>, %1
257  ret <2 x double> %2
258
259; FAULT-LABEL: d2rsqrt:
260; FAULT-NEXT: BB#0
261; FAULT-NEXT: fsqrt
262
263; CHECK-LABEL: d2rsqrt:
264; CHECK-NEXT: BB#0
265; CHECK-NEXT: frsqrte [[RA:v[0-7]\.2d]]
266; CHECK-NEXT: fmul [[RB:v[0-7]\.2d]], [[RA]], [[RA]]
267; CHECK-NEXT: frsqrts {{v[0-7]\.2d(, v[0-7]\.2d)?}}, [[RB]]
268; CHECK: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
269; CHECK: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
270; CHECK-NOT: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
271; CHECK-NOT: fcmeq {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, #0
272}
273
274define <4 x double> @d4rsqrt(<4 x double> %a) #0 {
275  %1 = tail call fast <4 x double> @llvm.sqrt.v4f64(<4 x double> %a)
276  %2 = fdiv fast <4 x double> <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>, %1
277  ret <4 x double> %2
278
279; FAULT-LABEL: d4rsqrt:
280; FAULT-NEXT: BB#0
281; FAULT-NEXT: fsqrt
282; FAULT-NEXT: fsqrt
283
284; CHECK-LABEL: d4rsqrt:
285; CHECK-NEXT: BB#0
286; CHECK-NEXT: frsqrte [[RA:v[0-7]\.2d]]
287; CHECK: fmul [[RB:v[0-7]\.2d]], [[RA]], [[RA]]
288; CHECK: frsqrts {{v[0-7]\.2d(, v[0-7]\.2d)?}}, [[RB]]
289; CHECK: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
290; CHECK: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
291; CHECK: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
292; CHECK: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
293; CHECK: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
294; CHECK-NOT: frsqrts {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, {{v[0-7]\.2d}}
295; CHECK-NOT: fcmeq {{v[0-7]\.2d}}, {{v[0-7]\.2d}}, #0
296}
297
298attributes #0 = { nounwind "unsafe-fp-math"="true" }
299