[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / InstCombine / pow-1.ll
blob957e2488b721b410e30c7488dd2a753969231396
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
11 ; rdar://7251832
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)
36   ret float %retval
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)
54   ret double %retval
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)
83   ret float %retval
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)
100   ret double %retval
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)
138   ret double %retval
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)
157   ret float %retval
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)
196   ret float %retval
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)
214   ret double %retval
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)
252   ret float %retval
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)
264   ret double %retval
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)
280   ret float %retval
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)
288   ret double %retval
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)
304   ret float %retval
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)
322   ret double %retval
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)
351   ret float %r
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>)
362   ret <2 x float> %r
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)
371   ret double %r
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>)
382   ret <2 x double> %r
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)
401   ret float %r
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)
420   ret float %r
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>)
431   ret <2 x float> %r
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)
440   ret double %r
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>)
451   ret <2 x double> %r
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)
463   ret double %retval
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)
476   ret float %retval
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)
487   ret double %retval