1 ; Test that the pow library call simplifier works correctly.
3 ; RUN: opt -instcombine -S < %s | FileCheck %s --check-prefixes=CHECK,ANY
4 ; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.9 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10
5 ; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios7.0 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10
6 ; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.8 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-NO-EXP10
7 ; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios6.0 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-NO-EXP10
8 ; RUN: opt -instcombine -S < %s -mtriple=x86_64-netbsd | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-NO-EXP10
9 ; RUN: opt -instcombine -S < %s -mtriple=arm-apple-tvos9.0 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10
10 ; RUN: opt -instcombine -S < %s -mtriple=arm-apple-watchos2.0 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10
12 ; RUN: opt -instcombine -S < %s -mtriple=i386-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,MSVC,VC32,CHECK-NO-EXP10
13 ; RUN: opt -instcombine -S < %s -mtriple=i386-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,MSVC,VC51,VC19,CHECK-NO-EXP10
14 ; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,MSVC,VC64,CHECK-NO-EXP10
15 ; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,MSVC,VC83,VC19,CHECK-NO-EXP10
17 ; NOTE: The readonly attribute on the pow call should be preserved
18 ; in the cases below where pow is transformed into another function call.
20 declare float @powf(float, float) nounwind readonly
21 declare double @pow(double, double) nounwind readonly
22 declare double @llvm.pow.f64(double, double)
23 declare <2 x float> @llvm.pow.v2f32(<2 x float>, <2 x float>) nounwind readonly
24 declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>) nounwind readonly
26 ; Check pow(1.0, x) -> 1.0.
28 define float @test_simplify1(float %x) {
29 ; CHECK-LABEL: @test_simplify1(
30 ; ANY-NEXT: ret float 1.000000e+00
31 ; VC32-NEXT: [[POW:%.*]] = call float @powf(float 1.000000e+00, float [[X:%.*]])
32 ; VC32-NEXT: ret float [[POW]]
33 ; VC64-NEXT: ret float 1.000000e+00
35 %retval = call float @powf(float 1.0, float %x)
39 define <2 x float> @test_simplify1v(<2 x float> %x) {
40 ; CHECK-LABEL: @test_simplify1v(
41 ; ANY-NEXT: ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
42 ; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> [[X:%.*]])
43 ; MSVC-NEXT: ret <2 x float> [[POW]]
45 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 1.0, float 1.0>, <2 x float> %x)
46 ret <2 x float> %retval
49 define double @test_simplify2(double %x) {
50 ; CHECK-LABEL: @test_simplify2(
51 ; CHECK-NEXT: ret double 1.000000e+00
53 %retval = call double @pow(double 1.0, double %x)
57 define <2 x double> @test_simplify2v(<2 x double> %x) {
58 ; CHECK-LABEL: @test_simplify2v(
59 ; ANY-NEXT: ret <2 x double> <double 1.000000e+00, double 1.000000e+00>
60 ; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 1.000000e+00, double 1.000000e+00>, <2 x double> [[X:%.*]])
61 ; MSVC-NEXT: ret <2 x double> [[POW]]
63 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 1.0, double 1.0>, <2 x double> %x)
64 ret <2 x double> %retval
67 ; Check pow(2.0 ** n, x) -> exp2(n * x).
69 define float @test_simplify3(float %x) {
70 ; CHECK-LABEL: @test_simplify3(
71 ; ANY-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[X:%.*]])
72 ; ANY-NEXT: ret float [[EXP2F]]
73 ; VC32-NEXT: [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]])
74 ; VC32-NEXT: ret float [[POW]]
75 ; VC51-NEXT: [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]])
76 ; VC51-NEXT: ret float [[POW]]
77 ; VC64-NEXT: [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]])
78 ; VC64-NEXT: ret float [[POW]]
79 ; VC83-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[X:%.*]])
80 ; VC83-NEXT: ret float [[EXP2F]]
82 %retval = call float @powf(float 2.0, float %x)
86 define double @test_simplify3n(double %x) {
87 ; CHECK-LABEL: @test_simplify3n(
88 ; ANY-NEXT: [[MUL:%.*]] = fmul double [[X:%.*]], -2.000000e+00
89 ; ANY-NEXT: [[EXP2:%.*]] = call double @exp2(double [[MUL]])
90 ; ANY-NEXT: ret double [[EXP2]]
91 ; VC19-NEXT: [[MUL:%.*]] = fmul double [[X:%.*]], -2.000000e+00
92 ; VC19-NEXT: [[EXP2:%.*]] = call double @exp2(double [[MUL]])
93 ; VC19-NEXT: ret double [[EXP2]]
94 ; VC32-NEXT: [[POW:%.*]] = call double @pow(double 2.500000e-01, double [[X:%.*]])
95 ; VC32-NEXT: ret double [[POW]]
96 ; VC64-NEXT: [[POW:%.*]] = call double @pow(double 2.500000e-01, double [[X:%.*]])
97 ; VC64-NEXT: ret double [[POW]]
99 %retval = call double @pow(double 0.25, double %x)
103 define <2 x float> @test_simplify3v(<2 x float> %x) {
104 ; CHECK-LABEL: @test_simplify3v(
105 ; ANY-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[X:%.*]])
106 ; ANY-NEXT: ret <2 x float> [[EXP2]]
107 ; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 2.000000e+00>, <2 x float> [[X:%.*]])
108 ; MSVC-NEXT: ret <2 x float> [[POW]]
110 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.0, float 2.0>, <2 x float> %x)
111 ret <2 x float> %retval
114 define <2 x double> @test_simplify3vn(<2 x double> %x) {
115 ; CHECK-LABEL: @test_simplify3vn(
116 ; ANY-NEXT: [[MUL:%.*]] = fmul <2 x double> [[X:%.*]], <double 2.000000e+00, double 2.000000e+00>
117 ; ANY-NEXT: [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[MUL]])
118 ; ANY-NEXT: ret <2 x double> [[EXP2]]
119 ; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 4.000000e+00, double 4.000000e+00>, <2 x double> [[X:%.*]])
120 ; MSVC-NEXT: ret <2 x double> [[POW]]
122 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 4.0, double 4.0>, <2 x double> %x)
123 ret <2 x double> %retval
126 define double @test_simplify4(double %x) {
127 ; CHECK-LABEL: @test_simplify4(
128 ; ANY-NEXT: [[EXP2:%.*]] = call double @exp2(double [[X:%.*]])
129 ; ANY-NEXT: ret double [[EXP2]]
130 ; VC19-NEXT: [[EXP2:%.*]] = call double @exp2(double [[X:%.*]])
131 ; VC19-NEXT: ret double [[EXP2]]
132 ; VC32-NEXT: [[POW:%.*]] = call double @pow(double 2.000000e+00, double [[X:%.*]])
133 ; VC32-NEXT: ret double [[POW]]
134 ; VC64-NEXT: [[POW:%.*]] = call double @pow(double 2.000000e+00, double [[X:%.*]])
135 ; VC64-NEXT: ret double [[POW]]
137 %retval = call double @pow(double 2.0, double %x)
141 define float @test_simplify4n(float %x) {
142 ; CHECK-LABEL: @test_simplify4n(
143 ; ANY-NEXT: [[MUL:%.*]] = fmul float [[X:%.*]], 3.000000e+00
144 ; ANY-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[MUL]])
145 ; ANY-NEXT: ret float [[EXP2F]]
146 ; VC32-NEXT: [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]])
147 ; VC32-NEXT: ret float [[POW]]
148 ; VC51-NEXT: [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]])
149 ; VC51-NEXT: ret float [[POW]]
150 ; VC64-NEXT: [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]])
151 ; VC64-NEXT: ret float [[POW]]
152 ; VC83-NEXT: [[MUL:%.*]] = fmul float [[X:%.*]], 3.000000e+00
153 ; VC83-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[MUL]])
154 ; VC83-NEXT: ret float [[EXP2F]]
156 %retval = call float @powf(float 8.0, float %x)
160 define <2 x double> @test_simplify4v(<2 x double> %x) {
161 ; CHECK-LABEL: @test_simplify4v(
162 ; ANY-NEXT: [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[X:%.*]])
163 ; ANY-NEXT: ret <2 x double> [[EXP2]]
164 ; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.000000e+00, double 2.000000e+00>, <2 x double> [[X:%.*]])
165 ; MSVC-NEXT: ret <2 x double> [[POW]]
167 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.0, double 2.0>, <2 x double> %x)
168 ret <2 x double> %retval
171 define <2 x float> @test_simplify4vn(<2 x float> %x) {
172 ; CHECK-LABEL: @test_simplify4vn(
173 ; ANY-NEXT: [[MUL:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
174 ; ANY-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[MUL]])
175 ; ANY-NEXT: ret <2 x float> [[EXP2]]
176 ; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 5.000000e-01, float 5.000000e-01>, <2 x float> [[X:%.*]])
177 ; MSVC-NEXT: ret <2 x float> [[POW]]
179 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 0.5, float 0.5>, <2 x float> %x)
180 ret <2 x float> %retval
183 ; Check pow(x, 0.0) -> 1.0.
185 define float @test_simplify5(float %x) {
186 ; CHECK-LABEL: @test_simplify5(
187 ; ANY-NEXT: ret float 1.000000e+00
188 ; VC32-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 0.000000e+00)
189 ; VC32-NEXT: ret float [[POW]]
190 ; VC51-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 0.000000e+00)
191 ; VC51-NEXT: ret float [[POW]]
192 ; VC64-NEXT: ret float 1.000000e+00
193 ; VC83-NEXT: ret float 1.000000e+00
195 %retval = call float @powf(float %x, float 0.0)
199 define <2 x float> @test_simplify5v(<2 x float> %x) {
200 ; CHECK-LABEL: @test_simplify5v(
201 ; ANY-NEXT: ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
202 ; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> zeroinitializer)
203 ; MSVC-NEXT: ret <2 x float> [[POW]]
205 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 0.0, float 0.0>)
206 ret <2 x float> %retval
209 define double @test_simplify6(double %x) {
210 ; CHECK-LABEL: @test_simplify6(
211 ; CHECK-NEXT: ret double 1.000000e+00
213 %retval = call double @pow(double %x, double 0.0)
217 define <2 x double> @test_simplify6v(<2 x double> %x) {
218 ; CHECK-LABEL: @test_simplify6v(
219 ; ANY-NEXT: ret <2 x double> <double 1.000000e+00, double 1.000000e+00>
220 ; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> zeroinitializer)
221 ; MSVC-NEXT: ret <2 x double> [[POW]]
223 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 0.0, double 0.0>)
224 ret <2 x double> %retval
227 ; Check pow(x, 0.5) -> fabs(sqrt(x)), where x != -infinity.
229 define float @test_simplify7(float %x) {
230 ; CHECK-LABEL: @test_simplify7(
231 ; ANY-NEXT: [[SQRTF:%.*]] = call float @sqrtf(float [[X:%.*]])
232 ; ANY-NEXT: [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRTF]])
233 ; ANY-NEXT: [[ISINF:%.*]] = fcmp oeq float [[X]], 0xFFF0000000000000
234 ; ANY-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], float 0x7FF0000000000000, float [[ABS]]
235 ; ANY-NEXT: ret float [[TMP1]]
236 ; VC32-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 5.000000e-01)
237 ; VC32-NEXT: ret float [[POW]]
238 ; VC51-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 5.000000e-01)
239 ; VC51-NEXT: ret float [[POW]]
240 ; VC64-NEXT: [[SQRTF:%.*]] = call float @sqrtf(float [[X:%.*]])
241 ; VC64-NEXT: [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRTF]])
242 ; VC64-NEXT: [[ISINF:%.*]] = fcmp oeq float [[X]], 0xFFF0000000000000
243 ; VC64-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], float 0x7FF0000000000000, float [[ABS]]
244 ; VC64-NEXT: ret float [[TMP1]]
245 ; VC83-NEXT: [[SQRTF:%.*]] = call float @sqrtf(float [[X:%.*]])
246 ; VC83-NEXT: [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRTF]])
247 ; VC83-NEXT: [[ISINF:%.*]] = fcmp oeq float [[X]], 0xFFF0000000000000
248 ; VC83-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], float 0x7FF0000000000000, float [[ABS]]
249 ; VC83-NEXT: ret float [[TMP1]]
251 %retval = call float @powf(float %x, float 0.5)
255 define double @test_simplify8(double %x) {
256 ; CHECK-LABEL: @test_simplify8(
257 ; CHECK-NEXT: [[SQRT:%.*]] = call double @sqrt(double [[X:%.*]])
258 ; CHECK-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]])
259 ; CHECK-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000
260 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]]
261 ; CHECK-NEXT: ret double [[TMP1]]
263 %retval = call double @pow(double %x, double 0.5)
267 ; Check pow(-infinity, 0.5) -> +infinity.
269 define float @test_simplify9(float %x) {
270 ; CHECK-LABEL: @test_simplify9(
271 ; ANY-NEXT: ret float 0x7FF0000000000000
272 ; VC32-NEXT: [[POW:%.*]] = call float @powf(float 0xFFF0000000000000, float 5.000000e-01)
273 ; VC32-NEXT: ret float [[POW]]
274 ; VC51-NEXT: [[POW:%.*]] = call float @powf(float 0xFFF0000000000000, float 5.000000e-01)
275 ; VC51-NEXT: ret float [[POW]]
276 ; VC64-NEXT: ret float 0x7FF0000000000000
277 ; VC83-NEXT: ret float 0x7FF0000000000000
279 %retval = call float @powf(float 0xFFF0000000000000, float 0.5)
283 define double @test_simplify10(double %x) {
284 ; CHECK-LABEL: @test_simplify10(
285 ; CHECK-NEXT: ret double 0x7FF0000000000000
287 %retval = call double @pow(double 0xFFF0000000000000, double 0.5)
291 ; Check pow(x, 1.0) -> x.
293 define float @test_simplify11(float %x) {
294 ; CHECK-LABEL: @test_simplify11(
295 ; ANY-NEXT: ret float [[X:%.*]]
296 ; VC32-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 1.000000e+00)
297 ; VC32-NEXT: ret float [[POW]]
298 ; VC51-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 1.000000e+00)
299 ; VC51-NEXT: ret float [[POW]]
300 ; VC64-NEXT: ret float [[X:%.*]]
301 ; VC83-NEXT: ret float [[X:%.*]]
303 %retval = call float @powf(float %x, float 1.0)
307 define <2 x float> @test_simplify11v(<2 x float> %x) {
308 ; CHECK-LABEL: @test_simplify11v(
309 ; ANY-NEXT: ret <2 x float> [[X:%.*]]
310 ; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> <float 1.000000e+00, float 1.000000e+00>)
311 ; MSVC-NEXT: ret <2 x float> [[POW]]
313 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 1.0, float 1.0>)
314 ret <2 x float> %retval
317 define double @test_simplify12(double %x) {
318 ; CHECK-LABEL: @test_simplify12(
319 ; CHECK-NEXT: ret double [[X:%.*]]
321 %retval = call double @pow(double %x, double 1.0)
325 define <2 x double> @test_simplify12v(<2 x double> %x) {
326 ; CHECK-LABEL: @test_simplify12v(
327 ; ANY-NEXT: ret <2 x double> [[X:%.*]]
328 ; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> <double 1.000000e+00, double 1.000000e+00>)
329 ; MSVC-NEXT: ret <2 x double> [[POW]]
331 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 1.0, double 1.0>)
332 ret <2 x double> %retval
335 ; Check pow(x, 2.0) -> x*x.
337 define float @pow2_strict(float %x) {
338 ; CHECK-LABEL: @pow2_strict(
339 ; ANY-NEXT: [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]]
340 ; ANY-NEXT: ret float [[SQUARE]]
341 ; VC32-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 2.000000e+00)
342 ; VC32-NEXT: ret float [[POW]]
343 ; VC51-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float 2.000000e+00)
344 ; VC51-NEXT: ret float [[POW]]
345 ; VC64-NEXT: [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]]
346 ; VC64-NEXT: ret float [[SQUARE]]
347 ; VC83-NEXT: [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]]
348 ; VC83-NEXT: ret float [[SQUARE]]
350 %r = call float @powf(float %x, float 2.0)
354 define <2 x float> @pow2_strictv(<2 x float> %x) {
355 ; CHECK-LABEL: @pow2_strictv(
356 ; ANY-NEXT: [[SQUARE:%.*]] = fmul <2 x float> [[X:%.*]], [[X]]
357 ; ANY-NEXT: ret <2 x float> [[SQUARE]]
358 ; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> <float 2.000000e+00, float 2.000000e+00>)
359 ; MSVC-NEXT: ret <2 x float> [[POW]]
361 %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 2.0, float 2.0>)
365 define double @pow2_double_strict(double %x) {
366 ; CHECK-LABEL: @pow2_double_strict(
367 ; CHECK-NEXT: [[SQUARE:%.*]] = fmul double [[X:%.*]], [[X]]
368 ; CHECK-NEXT: ret double [[SQUARE]]
370 %r = call double @pow(double %x, double 2.0)
374 define <2 x double> @pow2_double_strictv(<2 x double> %x) {
375 ; CHECK-LABEL: @pow2_double_strictv(
376 ; ANY-NEXT: [[SQUARE:%.*]] = fmul <2 x double> [[X:%.*]], [[X]]
377 ; ANY-NEXT: ret <2 x double> [[SQUARE]]
378 ; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> <double 2.000000e+00, double 2.000000e+00>)
379 ; MSVC-NEXT: ret <2 x double> [[POW]]
381 %r = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 2.0, double 2.0>)
385 ; Don't drop the FMF - PR35601 ( https://bugs.llvm.org/show_bug.cgi?id=35601 )
387 define float @pow2_fast(float %x) {
388 ; CHECK-LABEL: @pow2_fast(
389 ; ANY-NEXT: [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]]
390 ; ANY-NEXT: ret float [[SQUARE]]
391 ; VC32-NEXT: [[POW:%.*]] = call fast float @powf(float [[X:%.*]], float 2.000000e+00)
392 ; VC32-NEXT: ret float [[POW]]
393 ; VC51-NEXT: [[POW:%.*]] = call fast float @powf(float [[X:%.*]], float 2.000000e+00)
394 ; VC51-NEXT: ret float [[POW]]
395 ; VC64-NEXT: [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]]
396 ; VC64-NEXT: ret float [[SQUARE]]
397 ; VC83-NEXT: [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]]
398 ; VC83-NEXT: ret float [[SQUARE]]
400 %r = call fast float @powf(float %x, float 2.0)
404 ; Check pow(x, -1.0) -> 1.0/x.
406 define float @pow_neg1_strict(float %x) {
407 ; CHECK-LABEL: @pow_neg1_strict(
408 ; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]]
409 ; ANY-NEXT: ret float [[RECIPROCAL]]
410 ; VC32-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float -1.000000e+00)
411 ; VC32-NEXT: ret float [[POW]]
412 ; VC51-NEXT: [[POW:%.*]] = call float @powf(float [[X:%.*]], float -1.000000e+00)
413 ; VC51-NEXT: ret float [[POW]]
414 ; VC64-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]]
415 ; VC64-NEXT: ret float [[RECIPROCAL]]
416 ; VC83-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]]
417 ; VC83-NEXT: ret float [[RECIPROCAL]]
419 %r = call float @powf(float %x, float -1.0)
423 define <2 x float> @pow_neg1_strictv(<2 x float> %x) {
424 ; CHECK-LABEL: @pow_neg1_strictv(
425 ; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, [[X:%.*]]
426 ; ANY-NEXT: ret <2 x float> [[RECIPROCAL]]
427 ; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> <float -1.000000e+00, float -1.000000e+00>)
428 ; MSVC-NEXT: ret <2 x float> [[POW]]
430 %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float -1.0, float -1.0>)
434 define double @pow_neg1_double_fast(double %x) {
435 ; CHECK-LABEL: @pow_neg1_double_fast(
436 ; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[X:%.*]]
437 ; CHECK-NEXT: ret double [[RECIPROCAL]]
439 %r = call fast double @pow(double %x, double -1.0)
443 define <2 x double> @pow_neg1_double_fastv(<2 x double> %x) {
444 ; CHECK-LABEL: @pow_neg1_double_fastv(
445 ; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv fast <2 x double> <double 1.000000e+00, double 1.000000e+00>, [[X:%.*]]
446 ; ANY-NEXT: ret <2 x double> [[RECIPROCAL]]
447 ; MSVC-NEXT: [[POW:%.*]] = call fast <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> <double -1.000000e+00, double -1.000000e+00>)
448 ; MSVC-NEXT: ret <2 x double> [[POW]]
450 %r = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double -1.0, double -1.0>)
454 define double @test_simplify17(double %x) {
455 ; CHECK-LABEL: @test_simplify17(
456 ; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X:%.*]])
457 ; CHECK-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]])
458 ; CHECK-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000
459 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]]
460 ; CHECK-NEXT: ret double [[TMP1]]
462 %retval = call double @llvm.pow.f64(double %x, double 0.5)
466 ; Check pow(10.0, x) -> __exp10(x) on OS X 10.9+ and iOS 7.0+.
468 define float @test_simplify18(float %x) {
469 ; CHECK-LABEL: @test_simplify18(
470 ; CHECK-EXP10-NEXT: [[__EXP10F:%.*]] = call float @__exp10f(float [[X:%.*]])
471 ; CHECK-EXP10-NEXT: ret float [[__EXP10F]]
472 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X:%.*]])
473 ; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]]
475 %retval = call float @powf(float 10.0, float %x)
479 define double @test_simplify19(double %x) {
480 ; CHECK-LABEL: @test_simplify19(
481 ; CHECK-EXP10-NEXT: [[__EXP10:%.*]] = call double @__exp10(double [[X:%.*]])
482 ; CHECK-EXP10-NEXT: ret double [[__EXP10]]
483 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X:%.*]])
484 ; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]]
486 %retval = call double @pow(double 10.0, double %x)