[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / pow-1.ll
blob22da98b96eec7070a15178f6e5357c8814dfd207
1 ; Test that the pow library call simplifier works correctly.
3 ; RUN: opt -instcombine -S < %s                                   | FileCheck %s --check-prefixes=CHECK,LIB,ANY
4 ; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.9  | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10
5 ; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios7.0         | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10
6 ; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.8  | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10
7 ; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios6.0         | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10
8 ; RUN: opt -instcombine -S < %s -mtriple=x86_64-netbsd            | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10
9 ; RUN: opt -instcombine -S < %s -mtriple=arm-apple-tvos9.0        | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10
10 ; RUN: opt -instcombine -S < %s -mtriple=arm-apple-watchos2.0     | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10
11 ; rdar://7251832
12 ; RUN: opt -instcombine -S < %s -mtriple=i386-pc-windows-msvc18   | FileCheck %s --check-prefixes=CHECK,LIB,MSVC,VC32,CHECK-NO-EXP10
13 ; RUN: opt -instcombine -S < %s -mtriple=i386-pc-windows-msvc     | FileCheck %s --check-prefixes=CHECK,LIB,MSVC,VC51,VC19,CHECK-NO-EXP10
14 ; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,LIB,MSVC,VC64,CHECK-NO-EXP10
15 ; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc   | FileCheck %s --check-prefixes=CHECK,LIB,MSVC,VC83,VC19,CHECK-NO-EXP10
16 ; RUN: opt -instcombine -S < %s -mtriple=amdgcn--                 | FileCheck %s --check-prefixes=CHECK,NOLIB,CHECK-NO-EXP10
18 ; NOTE: The readonly attribute on the pow call should be preserved
19 ; in the cases below where pow is transformed into another function call.
21 declare float @powf(float, float) nounwind readonly
22 declare float @llvm.pow.f32(float, float)
23 declare double @pow(double, double) nounwind readonly
24 declare double @llvm.pow.f64(double, double)
25 declare <2 x float> @llvm.pow.v2f32(<2 x float>, <2 x float>) nounwind readonly
26 declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>) nounwind readonly
28 ; Check pow(1.0, x) -> 1.0.
30 define float @test_simplify1(float %x) {
31 ; CHECK-LABEL: @test_simplify1(
32 ; ANY-NEXT:    ret float 1.000000e+00
33 ; VC32-NEXT:   [[POW:%.*]] = call float @powf(float 1.000000e+00, float [[X:%.*]])
34 ; VC32-NEXT:   ret float [[POW]]
35 ; VC64-NEXT:   ret float 1.000000e+00
36 ; NOLIB-NEXT:    [[POW:%.*]] = call float @powf(float 1.000000e+00, float [[X:%.*]])
37 ; NOLIB-NEXT:    ret float [[POW]]
39   %retval = call float @powf(float 1.0, float %x)
40   ret float %retval
43 define <2 x float> @test_simplify1v(<2 x float> %x) {
44 ; CHECK-LABEL: @test_simplify1v(
45 ; CHECK-NEXT:    ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
47   %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 1.0, float 1.0>, <2 x float> %x)
48   ret <2 x float> %retval
51 define double @test_simplify2(double %x) {
52 ; CHECK-LABEL: @test_simplify2(
53 ; LIB-NEXT:    ret double 1.000000e+00
54 ; NOLIB-NEXT:    [[POW:%.*]] = call double @pow(double 1.000000e+00, double [[X:%.*]])
55 ; NOLIB-NEXT:    ret double [[POW]]
57   %retval = call double @pow(double 1.0, double %x)
58   ret double %retval
61 define <2 x double> @test_simplify2v(<2 x double> %x) {
62 ; CHECK-LABEL: @test_simplify2v(
63 ; CHECK-NEXT:    ret <2 x double> <double 1.000000e+00, double 1.000000e+00>
65   %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 1.0, double 1.0>, <2 x double> %x)
66   ret <2 x double> %retval
69 ; Check pow(2.0 ** n, x) -> exp2(n * x).
71 define float @test_simplify3(float %x) {
72 ; CHECK-LABEL: @test_simplify3(
73 ; ANY-NEXT:    [[EXP2F:%.*]] = call float @exp2f(float [[X:%.*]])
74 ; ANY-NEXT:    ret float [[EXP2F]]
75 ; VC32-NEXT:   [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]])
76 ; VC32-NEXT:   ret float [[POW]]
77 ; VC51-NEXT:   [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]])
78 ; VC51-NEXT:   ret float [[POW]]
79 ; VC64-NEXT:   [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]])
80 ; VC64-NEXT:   ret float [[POW]]
81 ; VC83-NEXT:   [[EXP2F:%.*]] = call float @exp2f(float [[X:%.*]])
82 ; VC83-NEXT:   ret float [[EXP2F]]
83 ; NOLIB-NEXT:    [[POW:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]])
84 ; NOLIB-NEXT:    ret float [[POW]]
86   %retval = call float @powf(float 2.0, float %x)
87   ret float %retval
90 define double @test_simplify3n(double %x) {
91 ; CHECK-LABEL: @test_simplify3n(
92 ; ANY-NEXT:    [[MUL:%.*]] = fmul double [[X:%.*]], -2.000000e+00
93 ; ANY-NEXT:    [[EXP2:%.*]] = call double @exp2(double [[MUL]])
94 ; ANY-NEXT:    ret double [[EXP2]]
95 ; VC19-NEXT:   [[MUL:%.*]] = fmul double [[X:%.*]], -2.000000e+00
96 ; VC19-NEXT:   [[EXP2:%.*]] = call double @exp2(double [[MUL]])
97 ; VC19-NEXT:   ret double [[EXP2]]
98 ; VC32-NEXT:   [[POW:%.*]] = call double @pow(double 2.500000e-01, double [[X:%.*]])
99 ; VC32-NEXT:   ret double [[POW]]
100 ; VC64-NEXT:   [[POW:%.*]] = call double @pow(double 2.500000e-01, double [[X:%.*]])
101 ; VC64-NEXT:   ret double [[POW]]
102 ; NOLIB-NEXT:    [[POW:%.*]] = call double @pow(double 2.500000e-01, double [[X:%.*]])
103 ; NOLIB-NEXT:    ret double [[POW]]
105   %retval = call double @pow(double 0.25, double %x)
106   ret double %retval
109 define <2 x float> @test_simplify3v(<2 x float> %x) {
110 ; CHECK-LABEL: @test_simplify3v(
111 ; ANY-NEXT:    [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[X:%.*]])
112 ; ANY-NEXT:    ret <2 x float> [[EXP2]]
113 ; 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:%.*]])
114 ; MSVC-NEXT:   ret <2 x float> [[POW]]
115 ; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
116 ; NOLIB-NEXT:    [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 2.000000e+00>, <2 x float> [[X:%.*]])
117 ; NOLIB-NEXT:    ret <2 x float> [[POW]]
119   %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.0, float 2.0>, <2 x float> %x)
120   ret <2 x float> %retval
123 define <2 x double> @test_simplify3vn(<2 x double> %x) {
124 ; CHECK-LABEL: @test_simplify3vn(
125 ; ANY-NEXT:    [[MUL:%.*]] = fmul <2 x double> [[X:%.*]], <double 2.000000e+00, double 2.000000e+00>
126 ; ANY-NEXT:    [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[MUL]])
127 ; ANY-NEXT:    ret <2 x double> [[EXP2]]
128 ; 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:%.*]])
129 ; MSVC-NEXT:   ret <2 x double> [[POW]]
130 ; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
131 ; NOLIB-NEXT:    [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 4.000000e+00, double 4.000000e+00>, <2 x double> [[X:%.*]])
132 ; NOLIB-NEXT:    ret <2 x double> [[POW]]
134   %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 4.0, double 4.0>, <2 x double> %x)
135   ret <2 x double> %retval
138 define double @test_simplify4(double %x) {
139 ; CHECK-LABEL: @test_simplify4(
140 ; ANY-NEXT:    [[EXP2:%.*]] = call double @exp2(double [[X:%.*]])
141 ; ANY-NEXT:    ret double [[EXP2]]
142 ; VC19-NEXT:   [[EXP2:%.*]] = call double @exp2(double [[X:%.*]])
143 ; VC19-NEXT:   ret double [[EXP2]]
144 ; VC32-NEXT:   [[POW:%.*]] = call double @pow(double 2.000000e+00, double [[X:%.*]])
145 ; VC32-NEXT:   ret double [[POW]]
146 ; VC64-NEXT:   [[POW:%.*]] = call double @pow(double 2.000000e+00, double [[X:%.*]])
147 ; VC64-NEXT:   ret double [[POW]]
148 ; NOLIB-NEXT:    [[POW:%.*]] = call double @pow(double 2.000000e+00, double [[X:%.*]])
149 ; NOLIB-NEXT:    ret double [[POW]]
151   %retval = call double @pow(double 2.0, double %x)
152   ret double %retval
155 define float @test_simplify4n(float %x) {
156 ; CHECK-LABEL: @test_simplify4n(
157 ; ANY-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 3.000000e+00
158 ; ANY-NEXT:    [[EXP2F:%.*]] = call float @exp2f(float [[MUL]])
159 ; ANY-NEXT:    ret float [[EXP2F]]
160 ; VC32-NEXT:   [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]])
161 ; VC32-NEXT:   ret float [[POW]]
162 ; VC51-NEXT:   [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]])
163 ; VC51-NEXT:   ret float [[POW]]
164 ; VC64-NEXT:   [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]])
165 ; VC64-NEXT:   ret float [[POW]]
166 ; VC83-NEXT:   [[MUL:%.*]] = fmul float [[X:%.*]], 3.000000e+00
167 ; VC83-NEXT:   [[EXP2F:%.*]] = call float @exp2f(float [[MUL]])
168 ; VC83-NEXT:   ret float [[EXP2F]]
169 ; NOLIB-NEXT:    [[POW:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]])
170 ; NOLIB-NEXT:    ret float [[POW]]
172   %retval = call float @powf(float 8.0, float %x)
173   ret float %retval
176 define <2 x double> @test_simplify4v(<2 x double> %x) {
177 ; CHECK-LABEL: @test_simplify4v(
178 ; ANY-NEXT:    [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[X:%.*]])
179 ; ANY-NEXT:    ret <2 x double> [[EXP2]]
180 ; 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:%.*]])
181 ; MSVC-NEXT:   ret <2 x double> [[POW]]
182 ; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
183 ; NOLIB-NEXT:    [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.000000e+00, double 2.000000e+00>, <2 x double> [[X:%.*]])
184 ; NOLIB-NEXT:    ret <2 x double> [[POW]]
186   %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.0, double 2.0>, <2 x double> %x)
187   ret <2 x double> %retval
190 define <2 x float> @test_simplify4vn(<2 x float> %x) {
191 ; CHECK-LABEL: @test_simplify4vn(
192 ; ANY-NEXT:    [[MUL:%.*]] = fneg <2 x float> [[X:%.*]]
193 ; ANY-NEXT:    [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[MUL]])
194 ; ANY-NEXT:    ret <2 x float> [[EXP2]]
195 ; 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:%.*]])
196 ; MSVC-NEXT:   ret <2 x float> [[POW]]
197 ; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
198 ; NOLIB-NEXT:    [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 5.000000e-01, float 5.000000e-01>, <2 x float> [[X:%.*]])
199 ; NOLIB-NEXT:    ret <2 x float> [[POW]]
201   %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 0.5, float 0.5>, <2 x float> %x)
202   ret <2 x float> %retval
205 ; Check pow(x, 0.0) -> 1.0.
207 define float @test_simplify5(float %x) {
208 ; CHECK-LABEL: @test_simplify5(
209 ; ANY-NEXT:    ret float 1.000000e+00
210 ; VC32-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float 0.000000e+00)
211 ; VC32-NEXT:   ret float [[POW]]
212 ; VC51-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float 0.000000e+00)
213 ; VC51-NEXT:   ret float [[POW]]
214 ; VC64-NEXT:   ret float 1.000000e+00
215 ; VC83-NEXT:   ret float 1.000000e+00
216 ; NOLIB-NEXT:    [[POW:%.*]] = call float @powf(float [[X:%.*]], float 0.000000e+00)
217 ; NOLIB-NEXT:    ret float [[POW]]
219   %retval = call float @powf(float %x, float 0.0)
220   ret float %retval
223 define <2 x float> @test_simplify5v(<2 x float> %x) {
224 ; CHECK-LABEL: @test_simplify5v(
225 ; CHECK-NEXT:    ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
227   %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 0.0, float 0.0>)
228   ret <2 x float> %retval
231 define double @test_simplify6(double %x) {
232 ; CHECK-LABEL: @test_simplify6(
233 ; LIB-NEXT:    ret double 1.000000e+00
234 ; NOLIB-NEXT:    [[POW:%.*]] = call double @pow(double [[X:%.*]], double 0.000000e+00)
235 ; NOLIB-NEXT:    ret double [[POW]]
237   %retval = call double @pow(double %x, double 0.0)
238   ret double %retval
241 define <2 x double> @test_simplify6v(<2 x double> %x) {
242 ; CHECK-LABEL: @test_simplify6v(
243 ; CHECK-NEXT:    ret <2 x double> <double 1.000000e+00, double 1.000000e+00>
245   %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 0.0, double 0.0>)
246   ret <2 x double> %retval
249 ; Check pow(x, 0.5) -> fabs(sqrt(x)), where x != -infinity.
251 define float @powf_libcall_half_ninf(float %x) {
252 ; CHECK-LABEL: @powf_libcall_half_ninf(
253 ; ANY-NEXT:    [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X:%.*]])
254 ; ANY-NEXT:    [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRTF]])
255 ; ANY-NEXT:    ret float [[ABS]]
256 ; VC32-NEXT:   [[POW:%.*]] = call ninf float @powf(float [[X:%.*]], float 5.000000e-01)
257 ; VC32-NEXT:   ret float [[POW]]
258 ; VC51-NEXT:   [[POW:%.*]] = call ninf float @powf(float [[X:%.*]], float 5.000000e-01)
259 ; VC51-NEXT:   ret float [[POW]]
260 ; VC64-NEXT:   [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X:%.*]])
261 ; VC64-NEXT:   [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRTF]])
262 ; VC64-NEXT:   ret float [[ABS]]
263 ; VC83-NEXT:   [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X:%.*]])
264 ; VC83-NEXT:   [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRTF]])
265 ; VC83-NEXT:   ret float [[ABS]]
266 ; NOLIB-NEXT:    [[POW:%.*]] = call ninf float @powf(float [[X:%.*]], float 5.000000e-01)
267 ; NOLIB-NEXT:    ret float [[POW]]
269   %retval = call ninf float @powf(float %x, float 0.5)
270   ret float %retval
273 ; Check pow(x, 0.5) where x may be -infinity does not call a library sqrt function.
275 define double @pow_libcall_half_no_FMF(double %x) {
276 ; CHECK-LABEL: @pow_libcall_half_no_FMF(
277 ; CHECK-NEXT:    [[POW:%.*]] = call double @pow(double [[X:%.*]], double 5.000000e-01)
278 ; CHECK-NEXT:    ret double [[POW]]
280   %retval = call double @pow(double %x, double 0.5)
281   ret double %retval
284 ; Check pow(-infinity, 0.5) -> +infinity.
286 define float @test_simplify9(float %x) {
287 ; CHECK-LABEL: @test_simplify9(
288 ; CHECK-NEXT:    ret float 0x7FF0000000000000
290   %retval = call float @llvm.pow.f32(float 0xFFF0000000000000, float 0.5)
291   ret float %retval
294 define double @test_simplify10(double %x) {
295 ; CHECK-LABEL: @test_simplify10(
296 ; CHECK-NEXT:    ret double 0x7FF0000000000000
298   %retval = call double @llvm.pow.f64(double 0xFFF0000000000000, double 0.5)
299   ret double %retval
302 ; Check pow(x, 1.0) -> x.
304 define float @test_simplify11(float %x) {
305 ; CHECK-LABEL: @test_simplify11(
306 ; ANY-NEXT:    ret float [[X:%.*]]
307 ; VC32-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float 1.000000e+00)
308 ; VC32-NEXT:   ret float [[POW]]
309 ; VC51-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float 1.000000e+00)
310 ; VC51-NEXT:   ret float [[POW]]
311 ; VC64-NEXT:   ret float [[X:%.*]]
312 ; VC83-NEXT:   ret float [[X:%.*]]
313 ; NOLIB-NEXT:    [[POW:%.*]] = call float @powf(float [[X:%.*]], float 1.000000e+00)
314 ; NOLIB-NEXT:    ret float [[POW]]
316   %retval = call float @powf(float %x, float 1.0)
317   ret float %retval
320 define <2 x float> @test_simplify11v(<2 x float> %x) {
321 ; CHECK-LABEL: @test_simplify11v(
322 ; CHECK-NEXT:    ret <2 x float> [[X:%.*]]
324   %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 1.0, float 1.0>)
325   ret <2 x float> %retval
328 define double @test_simplify12(double %x) {
329 ; CHECK-LABEL: @test_simplify12(
330 ; LIB-NEXT:    ret double [[X:%.*]]
331 ; NOLIB-NEXT:    [[POW:%.*]] = call double @pow(double [[X:%.*]], double 1.000000e+00)
332 ; NOLIB-NEXT:    ret double [[POW]]
334   %retval = call double @pow(double %x, double 1.0)
335   ret double %retval
338 define <2 x double> @test_simplify12v(<2 x double> %x) {
339 ; CHECK-LABEL: @test_simplify12v(
340 ; CHECK-NEXT:    ret <2 x double> [[X:%.*]]
342   %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 1.0, double 1.0>)
343   ret <2 x double> %retval
346 ; Check pow(x, 2.0) -> x*x.
348 define float @pow2_strict(float %x) {
349 ; CHECK-LABEL: @pow2_strict(
350 ; ANY-NEXT:    [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]]
351 ; ANY-NEXT:    ret float [[SQUARE]]
352 ; VC32-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float 2.000000e+00)
353 ; VC32-NEXT:   ret float [[POW]]
354 ; VC51-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float 2.000000e+00)
355 ; VC51-NEXT:   ret float [[POW]]
356 ; VC64-NEXT:   [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]]
357 ; VC64-NEXT:   ret float [[SQUARE]]
358 ; VC83-NEXT:   [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]]
359 ; VC83-NEXT:   ret float [[SQUARE]]
360 ; NOLIB-NEXT:    [[POW:%.*]] = call float @powf(float [[X:%.*]], float 2.000000e+00)
361 ; NOLIB-NEXT:    ret float [[POW]]
363   %r = call float @powf(float %x, float 2.0)
364   ret float %r
367 define <2 x float> @pow2_strictv(<2 x float> %x) {
368 ; CHECK-LABEL: @pow2_strictv(
369 ; CHECK-NEXT:    [[SQUARE:%.*]] = fmul <2 x float> [[X:%.*]], [[X]]
370 ; CHECK-NEXT:    ret <2 x float> [[SQUARE]]
372   %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 2.0, float 2.0>)
373   ret <2 x float> %r
376 define double @pow2_double_strict(double %x) {
377 ; CHECK-LABEL: @pow2_double_strict(
378 ; LIB-NEXT:    [[SQUARE:%.*]] = fmul double [[X:%.*]], [[X]]
379 ; LIB-NEXT:    ret double [[SQUARE]]
380 ; NOLIB-NEXT:    [[POW:%.*]] = call double @pow(double [[X:%.*]], double 2.000000e+00)
381 ; NOLIB-NEXT:    ret double [[POW]]
383   %r = call double @pow(double %x, double 2.0)
384   ret double %r
387 define <2 x double> @pow2_double_strictv(<2 x double> %x) {
388 ; CHECK-LABEL: @pow2_double_strictv(
389 ; CHECK-NEXT:    [[SQUARE:%.*]] = fmul <2 x double> [[X:%.*]], [[X]]
390 ; CHECK-NEXT:    ret <2 x double> [[SQUARE]]
392   %r = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 2.0, double 2.0>)
393   ret <2 x double> %r
396 ; Don't drop the FMF - PR35601 ( https://bugs.llvm.org/show_bug.cgi?id=35601 )
398 define float @pow2_fast(float %x) {
399 ; CHECK-LABEL: @pow2_fast(
400 ; ANY-NEXT:    [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]]
401 ; ANY-NEXT:    ret float [[SQUARE]]
402 ; VC32-NEXT:   [[POW:%.*]] = call fast float @powf(float [[X:%.*]], float 2.000000e+00)
403 ; VC32-NEXT:   ret float [[POW]]
404 ; VC51-NEXT:   [[POW:%.*]] = call fast float @powf(float [[X:%.*]], float 2.000000e+00)
405 ; VC51-NEXT:   ret float [[POW]]
406 ; VC64-NEXT:   [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]]
407 ; VC64-NEXT:   ret float [[SQUARE]]
408 ; VC83-NEXT:   [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]]
409 ; VC83-NEXT:   ret float [[SQUARE]]
410 ; NOLIB-NEXT:    [[POW:%.*]] = call fast float @powf(float [[X:%.*]], float 2.000000e+00)
411 ; NOLIB-NEXT:    ret float [[POW]]
413   %r = call fast float @powf(float %x, float 2.0)
414   ret float %r
417 ; Check pow(x, -1.0) -> 1.0/x.
419 define float @pow_neg1_strict(float %x) {
420 ; CHECK-LABEL: @pow_neg1_strict(
421 ; ANY-NEXT:    [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]]
422 ; ANY-NEXT:    ret float [[RECIPROCAL]]
423 ; VC32-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float -1.000000e+00)
424 ; VC32-NEXT:   ret float [[POW]]
425 ; VC51-NEXT:   [[POW:%.*]] = call float @powf(float [[X:%.*]], float -1.000000e+00)
426 ; VC51-NEXT:   ret float [[POW]]
427 ; VC64-NEXT:   [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]]
428 ; VC64-NEXT:   ret float [[RECIPROCAL]]
429 ; VC83-NEXT:   [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]]
430 ; VC83-NEXT:   ret float [[RECIPROCAL]]
431 ; NOLIB-NEXT:    [[POW:%.*]] = call float @powf(float [[X:%.*]], float -1.000000e+00)
432 ; NOLIB-NEXT:    ret float [[POW]]
434   %r = call float @powf(float %x, float -1.0)
435   ret float %r
438 define <2 x float> @pow_neg1_strictv(<2 x float> %x) {
439 ; CHECK-LABEL: @pow_neg1_strictv(
440 ; CHECK-NEXT:    [[RECIPROCAL:%.*]] = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, [[X:%.*]]
441 ; CHECK-NEXT:    ret <2 x float> [[RECIPROCAL]]
443   %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float -1.0, float -1.0>)
444   ret <2 x float> %r
447 define double @pow_neg1_double_fast(double %x) {
448 ; CHECK-LABEL: @pow_neg1_double_fast(
449 ; LIB-NEXT:    [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[X:%.*]]
450 ; LIB-NEXT:    ret double [[RECIPROCAL]]
451 ; NOLIB-NEXT:    [[POW:%.*]] = call fast double @pow(double [[X:%.*]], double -1.000000e+00)
452 ; NOLIB-NEXT:    ret double [[POW]]
454   %r = call fast double @pow(double %x, double -1.0)
455   ret double %r
458 define <2 x double> @pow_neg1_double_fastv(<2 x double> %x) {
459 ; CHECK-LABEL: @pow_neg1_double_fastv(
460 ; CHECK-NEXT:    [[RECIPROCAL:%.*]] = fdiv fast <2 x double> <double 1.000000e+00, double 1.000000e+00>, [[X:%.*]]
461 ; CHECK-NEXT:    ret <2 x double> [[RECIPROCAL]]
463   %r = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double -1.0, double -1.0>)
464   ret <2 x double> %r
467 define double @pow_intrinsic_half_no_FMF(double %x) {
468 ; CHECK-LABEL: @pow_intrinsic_half_no_FMF(
469 ; CHECK-NEXT:    [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X:%.*]])
470 ; CHECK-NEXT:    [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]])
471 ; CHECK-NEXT:    [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000
472 ; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]]
473 ; CHECK-NEXT:    ret double [[TMP1]]
475   %retval = call double @llvm.pow.f64(double %x, double 0.5)
476   ret double %retval
479 ; Check pow(10.0, x) -> __exp10(x) on OS X 10.9+ and iOS 7.0+.
481 define float @test_simplify18(float %x) {
482 ; CHECK-LABEL:          @test_simplify18(
483 ; CHECK-EXP10-NEXT:     [[__EXP10F:%.*]] = call float @__exp10f(float [[X:%.*]])
484 ; CHECK-EXP10-NEXT:     ret float [[__EXP10F]]
485 ; CHECK-NO-EXP10-NEXT:  [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X:%.*]])
486 ; CHECK-NO-EXP10-NEXT:  ret float [[RETVAL]]
488   %retval = call float @powf(float 10.0, float %x)
489   ret float %retval
492 define double @test_simplify19(double %x) {
493 ; CHECK-LABEL:          @test_simplify19(
494 ; CHECK-EXP10-NEXT:     [[__EXP10:%.*]] = call double @__exp10(double [[X:%.*]])
495 ; CHECK-EXP10-NEXT:     ret double [[__EXP10]]
496 ; CHECK-NO-EXP10-NEXT:  [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X:%.*]])
497 ; CHECK-NO-EXP10-NEXT:  ret double [[RETVAL]]
499   %retval = call double @pow(double 10.0, double %x)
500   ret double %retval