1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2 ; Test that the pow library call simplifier works correctly.
4 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s --check-prefixes=CHECK,LIB,ANY
5 ; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-apple-macosx10.9 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10
6 ; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-ios7.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10
7 ; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-apple-macosx10.8 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10
8 ; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-ios6.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10
9 ; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-netbsd | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10
10 ; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-tvos9.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10
11 ; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-watchos2.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10
13 ; RUN: opt -passes=instcombine -S < %s -mtriple=i386-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC32
14 ; RUN: opt -passes=instcombine -S < %s -mtriple=i386-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC19,VC51
15 ; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC64
16 ; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,LIB,CHECK-NO-EXP10,VC19,VC83
17 ; RUN: opt -passes=instcombine -S < %s -mtriple=amdgcn-- | FileCheck %s --check-prefixes=CHECK,CHECK-NO-EXP10,NOLIB
19 ; NOTE: The readonly attribute on the pow call should be preserved
20 ; in the cases below where pow is transformed into another function call.
22 declare float @powf(float, float)
23 declare float @llvm.pow.f32(float, float)
24 declare float @llvm.fabs.f32(float)
25 declare double @pow(double, double)
26 declare double @llvm.pow.f64(double, double)
27 declare <2 x float> @llvm.pow.v2f32(<2 x float>, <2 x float>) nounwind readonly
28 declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>) nounwind readonly
29 declare void @llvm.assume(i1 noundef)
31 ; Check pow(1.0, x) -> 1.0.
33 define float @test_simplify1(float %x) {
34 ; ANY-LABEL: define float @test_simplify1(
35 ; ANY-SAME: float [[X:%.*]]) {
36 ; ANY-NEXT: ret float 1.000000e+00
38 ; VC32-LABEL: define float @test_simplify1(
39 ; VC32-SAME: float [[X:%.*]]) {
40 ; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]])
41 ; VC32-NEXT: ret float [[RETVAL]]
43 ; VC51-LABEL: define float @test_simplify1(
44 ; VC51-SAME: float [[X:%.*]]) {
45 ; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]])
46 ; VC51-NEXT: ret float [[RETVAL]]
48 ; VC64-LABEL: define float @test_simplify1(
49 ; VC64-SAME: float [[X:%.*]]) {
50 ; VC64-NEXT: ret float 1.000000e+00
52 ; VC83-LABEL: define float @test_simplify1(
53 ; VC83-SAME: float [[X:%.*]]) {
54 ; VC83-NEXT: ret float 1.000000e+00
56 ; NOLIB-LABEL: define float @test_simplify1(
57 ; NOLIB-SAME: float [[X:%.*]]) {
58 ; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]])
59 ; NOLIB-NEXT: ret float [[RETVAL]]
61 %retval = call float @powf(float 1.0, float %x)
65 define float @test_simplify1_noerrno(float %x) {
66 ; ANY-LABEL: define float @test_simplify1_noerrno(
67 ; ANY-SAME: float [[X:%.*]]) {
68 ; ANY-NEXT: ret float 1.000000e+00
70 ; VC32-LABEL: define float @test_simplify1_noerrno(
71 ; VC32-SAME: float [[X:%.*]]) {
72 ; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]]) #[[ATTR2:[0-9]+]]
73 ; VC32-NEXT: ret float [[RETVAL]]
75 ; VC51-LABEL: define float @test_simplify1_noerrno(
76 ; VC51-SAME: float [[X:%.*]]) {
77 ; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]]) #[[ATTR2:[0-9]+]]
78 ; VC51-NEXT: ret float [[RETVAL]]
80 ; VC64-LABEL: define float @test_simplify1_noerrno(
81 ; VC64-SAME: float [[X:%.*]]) {
82 ; VC64-NEXT: ret float 1.000000e+00
84 ; VC83-LABEL: define float @test_simplify1_noerrno(
85 ; VC83-SAME: float [[X:%.*]]) {
86 ; VC83-NEXT: ret float 1.000000e+00
88 ; NOLIB-LABEL: define float @test_simplify1_noerrno(
89 ; NOLIB-SAME: float [[X:%.*]]) {
90 ; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X]]) #[[ATTR2:[0-9]+]]
91 ; NOLIB-NEXT: ret float [[RETVAL]]
93 %retval = call float @powf(float 1.0, float %x) #0
97 define <2 x float> @test_simplify1v(<2 x float> %x) {
98 ; CHECK-LABEL: define <2 x float> @test_simplify1v(
99 ; CHECK-SAME: <2 x float> [[X:%.*]]) {
100 ; CHECK-NEXT: ret <2 x float> splat (float 1.000000e+00)
102 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 1.0, float 1.0>, <2 x float> %x)
103 ret <2 x float> %retval
106 define double @test_simplify2(double %x) {
107 ; LIB-LABEL: define double @test_simplify2(
108 ; LIB-SAME: double [[X:%.*]]) {
109 ; LIB-NEXT: ret double 1.000000e+00
111 ; NOLIB-LABEL: define double @test_simplify2(
112 ; NOLIB-SAME: double [[X:%.*]]) {
113 ; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+00, double [[X]])
114 ; NOLIB-NEXT: ret double [[RETVAL]]
116 %retval = call double @pow(double 1.0, double %x)
120 define double @test_simplify2_noerrno(double %x) {
121 ; LIB-LABEL: define double @test_simplify2_noerrno(
122 ; LIB-SAME: double [[X:%.*]]) {
123 ; LIB-NEXT: ret double 1.000000e+00
125 ; NOLIB-LABEL: define double @test_simplify2_noerrno(
126 ; NOLIB-SAME: double [[X:%.*]]) {
127 ; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+00, double [[X]]) #[[ATTR2]]
128 ; NOLIB-NEXT: ret double [[RETVAL]]
130 %retval = call double @pow(double 1.0, double %x) #0
134 define <2 x double> @test_simplify2v(<2 x double> %x) {
135 ; CHECK-LABEL: define <2 x double> @test_simplify2v(
136 ; CHECK-SAME: <2 x double> [[X:%.*]]) {
137 ; CHECK-NEXT: ret <2 x double> splat (double 1.000000e+00)
139 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 1.0, double 1.0>, <2 x double> %x)
140 ret <2 x double> %retval
143 ; Check pow(2.0 ** n, x) -> exp2(n * x).
145 define float @test_simplify3(float %x) {
146 ; ANY-LABEL: define float @test_simplify3(
147 ; ANY-SAME: float [[X:%.*]]) {
148 ; ANY-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[X]])
149 ; ANY-NEXT: ret float [[EXP2F]]
151 ; VC32-LABEL: define float @test_simplify3(
152 ; VC32-SAME: float [[X:%.*]]) {
153 ; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]])
154 ; VC32-NEXT: ret float [[RETVAL]]
156 ; VC51-LABEL: define float @test_simplify3(
157 ; VC51-SAME: float [[X:%.*]]) {
158 ; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]])
159 ; VC51-NEXT: ret float [[RETVAL]]
161 ; VC64-LABEL: define float @test_simplify3(
162 ; VC64-SAME: float [[X:%.*]]) {
163 ; VC64-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]])
164 ; VC64-NEXT: ret float [[RETVAL]]
166 ; VC83-LABEL: define float @test_simplify3(
167 ; VC83-SAME: float [[X:%.*]]) {
168 ; VC83-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[X]])
169 ; VC83-NEXT: ret float [[EXP2F]]
171 ; NOLIB-LABEL: define float @test_simplify3(
172 ; NOLIB-SAME: float [[X:%.*]]) {
173 ; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]])
174 ; NOLIB-NEXT: ret float [[RETVAL]]
176 %retval = call float @powf(float 2.0, float %x)
180 define float @test_simplify3_noerrno(float %x) {
181 ; ANY-LABEL: define float @test_simplify3_noerrno(
182 ; ANY-SAME: float [[X:%.*]]) {
183 ; ANY-NEXT: [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[X]])
184 ; ANY-NEXT: ret float [[EXP2]]
186 ; VC32-LABEL: define float @test_simplify3_noerrno(
187 ; VC32-SAME: float [[X:%.*]]) {
188 ; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) #[[ATTR2]]
189 ; VC32-NEXT: ret float [[RETVAL]]
191 ; VC51-LABEL: define float @test_simplify3_noerrno(
192 ; VC51-SAME: float [[X:%.*]]) {
193 ; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) #[[ATTR2]]
194 ; VC51-NEXT: ret float [[RETVAL]]
196 ; VC64-LABEL: define float @test_simplify3_noerrno(
197 ; VC64-SAME: float [[X:%.*]]) {
198 ; VC64-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) #[[ATTR2:[0-9]+]]
199 ; VC64-NEXT: ret float [[RETVAL]]
201 ; VC83-LABEL: define float @test_simplify3_noerrno(
202 ; VC83-SAME: float [[X:%.*]]) {
203 ; VC83-NEXT: [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[X]])
204 ; VC83-NEXT: ret float [[EXP2]]
206 ; NOLIB-LABEL: define float @test_simplify3_noerrno(
207 ; NOLIB-SAME: float [[X:%.*]]) {
208 ; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X]]) #[[ATTR2]]
209 ; NOLIB-NEXT: ret float [[RETVAL]]
211 %retval = call float @powf(float 2.0, float %x) #0
215 define double @test_simplify3n_noerrno(double %x) {
216 ; ANY-LABEL: define double @test_simplify3n_noerrno(
217 ; ANY-SAME: double [[X:%.*]]) {
218 ; ANY-NEXT: [[MUL:%.*]] = fmul double [[X]], -2.000000e+00
219 ; ANY-NEXT: [[EXP2:%.*]] = call double @llvm.exp2.f64(double [[MUL]])
220 ; ANY-NEXT: ret double [[EXP2]]
222 ; VC32-LABEL: define double @test_simplify3n_noerrno(
223 ; VC32-SAME: double [[X:%.*]]) {
224 ; VC32-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.500000e-01, double [[X]]) #[[ATTR2]]
225 ; VC32-NEXT: ret double [[RETVAL]]
227 ; VC19-LABEL: define double @test_simplify3n_noerrno(
228 ; VC19-SAME: double [[X:%.*]]) {
229 ; VC19-NEXT: [[MUL:%.*]] = fmul double [[X]], -2.000000e+00
230 ; VC19-NEXT: [[EXP2:%.*]] = call double @llvm.exp2.f64(double [[MUL]])
231 ; VC19-NEXT: ret double [[EXP2]]
233 ; VC64-LABEL: define double @test_simplify3n_noerrno(
234 ; VC64-SAME: double [[X:%.*]]) {
235 ; VC64-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.500000e-01, double [[X]]) #[[ATTR2]]
236 ; VC64-NEXT: ret double [[RETVAL]]
238 ; NOLIB-LABEL: define double @test_simplify3n_noerrno(
239 ; NOLIB-SAME: double [[X:%.*]]) {
240 ; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.500000e-01, double [[X]]) #[[ATTR2]]
241 ; NOLIB-NEXT: ret double [[RETVAL]]
243 %retval = call double @pow(double 0.25, double %x) #0
247 ; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
248 define <2 x float> @test_simplify3v(<2 x float> %x) {
249 ; ANY-LABEL: define <2 x float> @test_simplify3v(
250 ; ANY-SAME: <2 x float> [[X:%.*]]) {
251 ; ANY-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[X]])
252 ; ANY-NEXT: ret <2 x float> [[EXP2]]
254 ; VC32-LABEL: define <2 x float> @test_simplify3v(
255 ; VC32-SAME: <2 x float> [[X:%.*]]) {
256 ; VC32-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 2.000000e+00), <2 x float> [[X]])
257 ; VC32-NEXT: ret <2 x float> [[RETVAL]]
259 ; VC19-LABEL: define <2 x float> @test_simplify3v(
260 ; VC19-SAME: <2 x float> [[X:%.*]]) {
261 ; VC19-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 2.000000e+00), <2 x float> [[X]])
262 ; VC19-NEXT: ret <2 x float> [[RETVAL]]
264 ; VC64-LABEL: define <2 x float> @test_simplify3v(
265 ; VC64-SAME: <2 x float> [[X:%.*]]) {
266 ; VC64-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 2.000000e+00), <2 x float> [[X]])
267 ; VC64-NEXT: ret <2 x float> [[RETVAL]]
269 ; NOLIB-LABEL: define <2 x float> @test_simplify3v(
270 ; NOLIB-SAME: <2 x float> [[X:%.*]]) {
271 ; NOLIB-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 2.000000e+00), <2 x float> [[X]])
272 ; NOLIB-NEXT: ret <2 x float> [[RETVAL]]
274 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.0, float 2.0>, <2 x float> %x)
275 ret <2 x float> %retval
278 ; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
279 define <2 x double> @test_simplify3vn(<2 x double> %x) {
280 ; ANY-LABEL: define <2 x double> @test_simplify3vn(
281 ; ANY-SAME: <2 x double> [[X:%.*]]) {
282 ; ANY-NEXT: [[MUL:%.*]] = fmul <2 x double> [[X]], splat (double 2.000000e+00)
283 ; ANY-NEXT: [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[MUL]])
284 ; ANY-NEXT: ret <2 x double> [[EXP2]]
286 ; VC32-LABEL: define <2 x double> @test_simplify3vn(
287 ; VC32-SAME: <2 x double> [[X:%.*]]) {
288 ; VC32-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 4.000000e+00), <2 x double> [[X]])
289 ; VC32-NEXT: ret <2 x double> [[RETVAL]]
291 ; VC19-LABEL: define <2 x double> @test_simplify3vn(
292 ; VC19-SAME: <2 x double> [[X:%.*]]) {
293 ; VC19-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 4.000000e+00), <2 x double> [[X]])
294 ; VC19-NEXT: ret <2 x double> [[RETVAL]]
296 ; VC64-LABEL: define <2 x double> @test_simplify3vn(
297 ; VC64-SAME: <2 x double> [[X:%.*]]) {
298 ; VC64-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 4.000000e+00), <2 x double> [[X]])
299 ; VC64-NEXT: ret <2 x double> [[RETVAL]]
301 ; NOLIB-LABEL: define <2 x double> @test_simplify3vn(
302 ; NOLIB-SAME: <2 x double> [[X:%.*]]) {
303 ; NOLIB-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 4.000000e+00), <2 x double> [[X]])
304 ; NOLIB-NEXT: ret <2 x double> [[RETVAL]]
306 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 4.0, double 4.0>, <2 x double> %x)
307 ret <2 x double> %retval
310 define double @test_simplify4(double %x) {
311 ; ANY-LABEL: define double @test_simplify4(
312 ; ANY-SAME: double [[X:%.*]]) {
313 ; ANY-NEXT: [[EXP2:%.*]] = call double @exp2(double [[X]])
314 ; ANY-NEXT: ret double [[EXP2]]
316 ; VC32-LABEL: define double @test_simplify4(
317 ; VC32-SAME: double [[X:%.*]]) {
318 ; VC32-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]])
319 ; VC32-NEXT: ret double [[RETVAL]]
321 ; VC19-LABEL: define double @test_simplify4(
322 ; VC19-SAME: double [[X:%.*]]) {
323 ; VC19-NEXT: [[EXP2:%.*]] = call double @exp2(double [[X]])
324 ; VC19-NEXT: ret double [[EXP2]]
326 ; VC64-LABEL: define double @test_simplify4(
327 ; VC64-SAME: double [[X:%.*]]) {
328 ; VC64-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]])
329 ; VC64-NEXT: ret double [[RETVAL]]
331 ; NOLIB-LABEL: define double @test_simplify4(
332 ; NOLIB-SAME: double [[X:%.*]]) {
333 ; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]])
334 ; NOLIB-NEXT: ret double [[RETVAL]]
336 %retval = call double @pow(double 2.0, double %x)
340 define double @test_simplify4_noerrno(double %x) {
341 ; ANY-LABEL: define double @test_simplify4_noerrno(
342 ; ANY-SAME: double [[X:%.*]]) {
343 ; ANY-NEXT: [[EXP2:%.*]] = call double @llvm.exp2.f64(double [[X]])
344 ; ANY-NEXT: ret double [[EXP2]]
346 ; VC32-LABEL: define double @test_simplify4_noerrno(
347 ; VC32-SAME: double [[X:%.*]]) {
348 ; VC32-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]]) #[[ATTR2]]
349 ; VC32-NEXT: ret double [[RETVAL]]
351 ; VC19-LABEL: define double @test_simplify4_noerrno(
352 ; VC19-SAME: double [[X:%.*]]) {
353 ; VC19-NEXT: [[EXP2:%.*]] = call double @llvm.exp2.f64(double [[X]])
354 ; VC19-NEXT: ret double [[EXP2]]
356 ; VC64-LABEL: define double @test_simplify4_noerrno(
357 ; VC64-SAME: double [[X:%.*]]) {
358 ; VC64-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]]) #[[ATTR2]]
359 ; VC64-NEXT: ret double [[RETVAL]]
361 ; NOLIB-LABEL: define double @test_simplify4_noerrno(
362 ; NOLIB-SAME: double [[X:%.*]]) {
363 ; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X]]) #[[ATTR2]]
364 ; NOLIB-NEXT: ret double [[RETVAL]]
366 %retval = call double @pow(double 2.0, double %x) #0
370 define float @test_simplify4n(float %x) {
371 ; ANY-LABEL: define float @test_simplify4n(
372 ; ANY-SAME: float [[X:%.*]]) {
373 ; ANY-NEXT: [[MUL:%.*]] = fmul float [[X]], 3.000000e+00
374 ; ANY-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[MUL]])
375 ; ANY-NEXT: ret float [[EXP2F]]
377 ; VC32-LABEL: define float @test_simplify4n(
378 ; VC32-SAME: float [[X:%.*]]) {
379 ; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]])
380 ; VC32-NEXT: ret float [[RETVAL]]
382 ; VC51-LABEL: define float @test_simplify4n(
383 ; VC51-SAME: float [[X:%.*]]) {
384 ; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]])
385 ; VC51-NEXT: ret float [[RETVAL]]
387 ; VC64-LABEL: define float @test_simplify4n(
388 ; VC64-SAME: float [[X:%.*]]) {
389 ; VC64-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]])
390 ; VC64-NEXT: ret float [[RETVAL]]
392 ; VC83-LABEL: define float @test_simplify4n(
393 ; VC83-SAME: float [[X:%.*]]) {
394 ; VC83-NEXT: [[MUL:%.*]] = fmul float [[X]], 3.000000e+00
395 ; VC83-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[MUL]])
396 ; VC83-NEXT: ret float [[EXP2F]]
398 ; NOLIB-LABEL: define float @test_simplify4n(
399 ; NOLIB-SAME: float [[X:%.*]]) {
400 ; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]])
401 ; NOLIB-NEXT: ret float [[RETVAL]]
403 %retval = call float @powf(float 8.0, float %x)
407 define float @test_simplify4n_noerrno(float %x) {
408 ; ANY-LABEL: define float @test_simplify4n_noerrno(
409 ; ANY-SAME: float [[X:%.*]]) {
410 ; ANY-NEXT: [[MUL:%.*]] = fmul float [[X]], 3.000000e+00
411 ; ANY-NEXT: [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[MUL]])
412 ; ANY-NEXT: ret float [[EXP2]]
414 ; VC32-LABEL: define float @test_simplify4n_noerrno(
415 ; VC32-SAME: float [[X:%.*]]) {
416 ; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) #[[ATTR2]]
417 ; VC32-NEXT: ret float [[RETVAL]]
419 ; VC51-LABEL: define float @test_simplify4n_noerrno(
420 ; VC51-SAME: float [[X:%.*]]) {
421 ; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) #[[ATTR2]]
422 ; VC51-NEXT: ret float [[RETVAL]]
424 ; VC64-LABEL: define float @test_simplify4n_noerrno(
425 ; VC64-SAME: float [[X:%.*]]) {
426 ; VC64-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) #[[ATTR2]]
427 ; VC64-NEXT: ret float [[RETVAL]]
429 ; VC83-LABEL: define float @test_simplify4n_noerrno(
430 ; VC83-SAME: float [[X:%.*]]) {
431 ; VC83-NEXT: [[MUL:%.*]] = fmul float [[X]], 3.000000e+00
432 ; VC83-NEXT: [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[MUL]])
433 ; VC83-NEXT: ret float [[EXP2]]
435 ; NOLIB-LABEL: define float @test_simplify4n_noerrno(
436 ; NOLIB-SAME: float [[X:%.*]]) {
437 ; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X]]) #[[ATTR2]]
438 ; NOLIB-NEXT: ret float [[RETVAL]]
440 %retval = call float @powf(float 8.0, float %x) #0
444 ; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
445 define <2 x double> @test_simplify4v(<2 x double> %x) {
446 ; ANY-LABEL: define <2 x double> @test_simplify4v(
447 ; ANY-SAME: <2 x double> [[X:%.*]]) {
448 ; ANY-NEXT: [[EXP2:%.*]] = call <2 x double> @llvm.exp2.v2f64(<2 x double> [[X]])
449 ; ANY-NEXT: ret <2 x double> [[EXP2]]
451 ; VC32-LABEL: define <2 x double> @test_simplify4v(
452 ; VC32-SAME: <2 x double> [[X:%.*]]) {
453 ; VC32-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 2.000000e+00), <2 x double> [[X]])
454 ; VC32-NEXT: ret <2 x double> [[RETVAL]]
456 ; VC19-LABEL: define <2 x double> @test_simplify4v(
457 ; VC19-SAME: <2 x double> [[X:%.*]]) {
458 ; VC19-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 2.000000e+00), <2 x double> [[X]])
459 ; VC19-NEXT: ret <2 x double> [[RETVAL]]
461 ; VC64-LABEL: define <2 x double> @test_simplify4v(
462 ; VC64-SAME: <2 x double> [[X:%.*]]) {
463 ; VC64-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 2.000000e+00), <2 x double> [[X]])
464 ; VC64-NEXT: ret <2 x double> [[RETVAL]]
466 ; NOLIB-LABEL: define <2 x double> @test_simplify4v(
467 ; NOLIB-SAME: <2 x double> [[X:%.*]]) {
468 ; NOLIB-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 2.000000e+00), <2 x double> [[X]])
469 ; NOLIB-NEXT: ret <2 x double> [[RETVAL]]
471 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.0, double 2.0>, <2 x double> %x)
472 ret <2 x double> %retval
475 ; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
476 define <2 x float> @test_simplify4vn(<2 x float> %x) {
477 ; ANY-LABEL: define <2 x float> @test_simplify4vn(
478 ; ANY-SAME: <2 x float> [[X:%.*]]) {
479 ; ANY-NEXT: [[MUL:%.*]] = fneg <2 x float> [[X]]
480 ; ANY-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[MUL]])
481 ; ANY-NEXT: ret <2 x float> [[EXP2]]
483 ; VC32-LABEL: define <2 x float> @test_simplify4vn(
484 ; VC32-SAME: <2 x float> [[X:%.*]]) {
485 ; VC32-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 5.000000e-01), <2 x float> [[X]])
486 ; VC32-NEXT: ret <2 x float> [[RETVAL]]
488 ; VC19-LABEL: define <2 x float> @test_simplify4vn(
489 ; VC19-SAME: <2 x float> [[X:%.*]]) {
490 ; VC19-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 5.000000e-01), <2 x float> [[X]])
491 ; VC19-NEXT: ret <2 x float> [[RETVAL]]
493 ; VC64-LABEL: define <2 x float> @test_simplify4vn(
494 ; VC64-SAME: <2 x float> [[X:%.*]]) {
495 ; VC64-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 5.000000e-01), <2 x float> [[X]])
496 ; VC64-NEXT: ret <2 x float> [[RETVAL]]
498 ; NOLIB-LABEL: define <2 x float> @test_simplify4vn(
499 ; NOLIB-SAME: <2 x float> [[X:%.*]]) {
500 ; NOLIB-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 5.000000e-01), <2 x float> [[X]])
501 ; NOLIB-NEXT: ret <2 x float> [[RETVAL]]
503 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 0.5, float 0.5>, <2 x float> %x)
504 ret <2 x float> %retval
507 ; Check pow(x, 0.0) -> 1.0.
509 define float @test_simplify5(float %x) {
510 ; ANY-LABEL: define float @test_simplify5(
511 ; ANY-SAME: float [[X:%.*]]) {
512 ; ANY-NEXT: ret float 1.000000e+00
514 ; VC32-LABEL: define float @test_simplify5(
515 ; VC32-SAME: float [[X:%.*]]) {
516 ; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00)
517 ; VC32-NEXT: ret float [[RETVAL]]
519 ; VC51-LABEL: define float @test_simplify5(
520 ; VC51-SAME: float [[X:%.*]]) {
521 ; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00)
522 ; VC51-NEXT: ret float [[RETVAL]]
524 ; VC64-LABEL: define float @test_simplify5(
525 ; VC64-SAME: float [[X:%.*]]) {
526 ; VC64-NEXT: ret float 1.000000e+00
528 ; VC83-LABEL: define float @test_simplify5(
529 ; VC83-SAME: float [[X:%.*]]) {
530 ; VC83-NEXT: ret float 1.000000e+00
532 ; NOLIB-LABEL: define float @test_simplify5(
533 ; NOLIB-SAME: float [[X:%.*]]) {
534 ; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00)
535 ; NOLIB-NEXT: ret float [[RETVAL]]
537 %retval = call float @powf(float %x, float 0.0)
541 define float @test_simplify5_noerrno(float %x) {
542 ; ANY-LABEL: define float @test_simplify5_noerrno(
543 ; ANY-SAME: float [[X:%.*]]) {
544 ; ANY-NEXT: ret float 1.000000e+00
546 ; VC32-LABEL: define float @test_simplify5_noerrno(
547 ; VC32-SAME: float [[X:%.*]]) {
548 ; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00) #[[ATTR2]]
549 ; VC32-NEXT: ret float [[RETVAL]]
551 ; VC51-LABEL: define float @test_simplify5_noerrno(
552 ; VC51-SAME: float [[X:%.*]]) {
553 ; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00) #[[ATTR2]]
554 ; VC51-NEXT: ret float [[RETVAL]]
556 ; VC64-LABEL: define float @test_simplify5_noerrno(
557 ; VC64-SAME: float [[X:%.*]]) {
558 ; VC64-NEXT: ret float 1.000000e+00
560 ; VC83-LABEL: define float @test_simplify5_noerrno(
561 ; VC83-SAME: float [[X:%.*]]) {
562 ; VC83-NEXT: ret float 1.000000e+00
564 ; NOLIB-LABEL: define float @test_simplify5_noerrno(
565 ; NOLIB-SAME: float [[X:%.*]]) {
566 ; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 0.000000e+00) #[[ATTR2]]
567 ; NOLIB-NEXT: ret float [[RETVAL]]
569 %retval = call float @powf(float %x, float 0.0) #0
573 define <2 x float> @test_simplify5v(<2 x float> %x) {
574 ; CHECK-LABEL: define <2 x float> @test_simplify5v(
575 ; CHECK-SAME: <2 x float> [[X:%.*]]) {
576 ; CHECK-NEXT: ret <2 x float> splat (float 1.000000e+00)
578 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 0.0, float 0.0>)
579 ret <2 x float> %retval
582 define double @test_simplify6(double %x) {
583 ; LIB-LABEL: define double @test_simplify6(
584 ; LIB-SAME: double [[X:%.*]]) {
585 ; LIB-NEXT: ret double 1.000000e+00
587 ; NOLIB-LABEL: define double @test_simplify6(
588 ; NOLIB-SAME: double [[X:%.*]]) {
589 ; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 0.000000e+00)
590 ; NOLIB-NEXT: ret double [[RETVAL]]
592 %retval = call double @pow(double %x, double 0.0)
596 define double @test_simplify6_noerrno(double %x) {
597 ; LIB-LABEL: define double @test_simplify6_noerrno(
598 ; LIB-SAME: double [[X:%.*]]) {
599 ; LIB-NEXT: ret double 1.000000e+00
601 ; NOLIB-LABEL: define double @test_simplify6_noerrno(
602 ; NOLIB-SAME: double [[X:%.*]]) {
603 ; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 0.000000e+00) #[[ATTR2]]
604 ; NOLIB-NEXT: ret double [[RETVAL]]
606 %retval = call double @pow(double %x, double 0.0) #0
610 define <2 x double> @test_simplify6v(<2 x double> %x) {
611 ; CHECK-LABEL: define <2 x double> @test_simplify6v(
612 ; CHECK-SAME: <2 x double> [[X:%.*]]) {
613 ; CHECK-NEXT: ret <2 x double> splat (double 1.000000e+00)
615 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 0.0, double 0.0>)
616 ret <2 x double> %retval
619 ; Check pow(x, 0.5) -> fabs(sqrt(x)), where x != -infinity.
621 define float @powf_libcall_half_ninf(float %x) {
622 ; ANY-LABEL: define float @powf_libcall_half_ninf(
623 ; ANY-SAME: float [[X:%.*]]) {
624 ; ANY-NEXT: [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]])
625 ; ANY-NEXT: [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRTF]])
626 ; ANY-NEXT: ret float [[ABS]]
628 ; VC32-LABEL: define float @powf_libcall_half_ninf(
629 ; VC32-SAME: float [[X:%.*]]) {
630 ; VC32-NEXT: [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01)
631 ; VC32-NEXT: ret float [[RETVAL]]
633 ; VC51-LABEL: define float @powf_libcall_half_ninf(
634 ; VC51-SAME: float [[X:%.*]]) {
635 ; VC51-NEXT: [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01)
636 ; VC51-NEXT: ret float [[RETVAL]]
638 ; VC64-LABEL: define float @powf_libcall_half_ninf(
639 ; VC64-SAME: float [[X:%.*]]) {
640 ; VC64-NEXT: [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]])
641 ; VC64-NEXT: [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRTF]])
642 ; VC64-NEXT: ret float [[ABS]]
644 ; VC83-LABEL: define float @powf_libcall_half_ninf(
645 ; VC83-SAME: float [[X:%.*]]) {
646 ; VC83-NEXT: [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]])
647 ; VC83-NEXT: [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRTF]])
648 ; VC83-NEXT: ret float [[ABS]]
650 ; NOLIB-LABEL: define float @powf_libcall_half_ninf(
651 ; NOLIB-SAME: float [[X:%.*]]) {
652 ; NOLIB-NEXT: [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01)
653 ; NOLIB-NEXT: ret float [[RETVAL]]
655 %retval = call ninf float @powf(float %x, float 0.5)
659 define float @powf_libcall_half_ninf_noerrno(float %x) {
660 ; ANY-LABEL: define float @powf_libcall_half_ninf_noerrno(
661 ; ANY-SAME: float [[X:%.*]]) {
662 ; ANY-NEXT: [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]])
663 ; ANY-NEXT: [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRT]])
664 ; ANY-NEXT: ret float [[ABS]]
666 ; VC32-LABEL: define float @powf_libcall_half_ninf_noerrno(
667 ; VC32-SAME: float [[X:%.*]]) {
668 ; VC32-NEXT: [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
669 ; VC32-NEXT: ret float [[RETVAL]]
671 ; VC51-LABEL: define float @powf_libcall_half_ninf_noerrno(
672 ; VC51-SAME: float [[X:%.*]]) {
673 ; VC51-NEXT: [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
674 ; VC51-NEXT: ret float [[RETVAL]]
676 ; VC64-LABEL: define float @powf_libcall_half_ninf_noerrno(
677 ; VC64-SAME: float [[X:%.*]]) {
678 ; VC64-NEXT: [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]])
679 ; VC64-NEXT: [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRT]])
680 ; VC64-NEXT: ret float [[ABS]]
682 ; VC83-LABEL: define float @powf_libcall_half_ninf_noerrno(
683 ; VC83-SAME: float [[X:%.*]]) {
684 ; VC83-NEXT: [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]])
685 ; VC83-NEXT: [[ABS:%.*]] = call ninf float @llvm.fabs.f32(float [[SQRT]])
686 ; VC83-NEXT: ret float [[ABS]]
688 ; NOLIB-LABEL: define float @powf_libcall_half_ninf_noerrno(
689 ; NOLIB-SAME: float [[X:%.*]]) {
690 ; NOLIB-NEXT: [[RETVAL:%.*]] = call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
691 ; NOLIB-NEXT: ret float [[RETVAL]]
693 %retval = call ninf float @powf(float %x, float 0.5) #0
697 ; Make sure assume works when inferring no infinities
698 define float @powf_libcall_half_assume_ninf_noerrno(float %x) {
699 ; ANY-LABEL: define float @powf_libcall_half_assume_ninf_noerrno(
700 ; ANY-SAME: float [[X:%.*]]) {
701 ; ANY-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
702 ; ANY-NEXT: [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000
703 ; ANY-NEXT: call void @llvm.assume(i1 [[NOT_INF]])
704 ; ANY-NEXT: [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[X]])
705 ; ANY-NEXT: [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
706 ; ANY-NEXT: ret float [[ABS]]
708 ; VC32-LABEL: define float @powf_libcall_half_assume_ninf_noerrno(
709 ; VC32-SAME: float [[X:%.*]]) {
710 ; VC32-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
711 ; VC32-NEXT: [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000
712 ; VC32-NEXT: call void @llvm.assume(i1 [[NOT_INF]])
713 ; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
714 ; VC32-NEXT: ret float [[RETVAL]]
716 ; VC51-LABEL: define float @powf_libcall_half_assume_ninf_noerrno(
717 ; VC51-SAME: float [[X:%.*]]) {
718 ; VC51-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
719 ; VC51-NEXT: [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000
720 ; VC51-NEXT: call void @llvm.assume(i1 [[NOT_INF]])
721 ; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
722 ; VC51-NEXT: ret float [[RETVAL]]
724 ; VC64-LABEL: define float @powf_libcall_half_assume_ninf_noerrno(
725 ; VC64-SAME: float [[X:%.*]]) {
726 ; VC64-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
727 ; VC64-NEXT: [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000
728 ; VC64-NEXT: call void @llvm.assume(i1 [[NOT_INF]])
729 ; VC64-NEXT: [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[X]])
730 ; VC64-NEXT: [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
731 ; VC64-NEXT: ret float [[ABS]]
733 ; VC83-LABEL: define float @powf_libcall_half_assume_ninf_noerrno(
734 ; VC83-SAME: float [[X:%.*]]) {
735 ; VC83-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
736 ; VC83-NEXT: [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000
737 ; VC83-NEXT: call void @llvm.assume(i1 [[NOT_INF]])
738 ; VC83-NEXT: [[SQRT:%.*]] = call float @llvm.sqrt.f32(float [[X]])
739 ; VC83-NEXT: [[ABS:%.*]] = call float @llvm.fabs.f32(float [[SQRT]])
740 ; VC83-NEXT: ret float [[ABS]]
742 ; NOLIB-LABEL: define float @powf_libcall_half_assume_ninf_noerrno(
743 ; NOLIB-SAME: float [[X:%.*]]) {
744 ; NOLIB-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X]])
745 ; NOLIB-NEXT: [[NOT_INF:%.*]] = fcmp one float [[FABS]], 0x7FF0000000000000
746 ; NOLIB-NEXT: call void @llvm.assume(i1 [[NOT_INF]])
747 ; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
748 ; NOLIB-NEXT: ret float [[RETVAL]]
750 %fabs = call float @llvm.fabs.f32(float %x)
751 %not.inf = fcmp one float %fabs, 0x7FF0000000000000
752 call void @llvm.assume(i1 %not.inf)
753 %retval = call float @powf(float %x, float 0.5) #0
757 define float @powf_libcall_half_ninf_tail(float %x) {
758 ; ANY-LABEL: define float @powf_libcall_half_ninf_tail(
759 ; ANY-SAME: float [[X:%.*]]) {
760 ; ANY-NEXT: [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]])
761 ; ANY-NEXT: [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRTF]])
762 ; ANY-NEXT: ret float [[ABS]]
764 ; VC32-LABEL: define float @powf_libcall_half_ninf_tail(
765 ; VC32-SAME: float [[X:%.*]]) {
766 ; VC32-NEXT: [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01)
767 ; VC32-NEXT: ret float [[RETVAL]]
769 ; VC51-LABEL: define float @powf_libcall_half_ninf_tail(
770 ; VC51-SAME: float [[X:%.*]]) {
771 ; VC51-NEXT: [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01)
772 ; VC51-NEXT: ret float [[RETVAL]]
774 ; VC64-LABEL: define float @powf_libcall_half_ninf_tail(
775 ; VC64-SAME: float [[X:%.*]]) {
776 ; VC64-NEXT: [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]])
777 ; VC64-NEXT: [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRTF]])
778 ; VC64-NEXT: ret float [[ABS]]
780 ; VC83-LABEL: define float @powf_libcall_half_ninf_tail(
781 ; VC83-SAME: float [[X:%.*]]) {
782 ; VC83-NEXT: [[SQRTF:%.*]] = call ninf float @sqrtf(float [[X]])
783 ; VC83-NEXT: [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRTF]])
784 ; VC83-NEXT: ret float [[ABS]]
786 ; NOLIB-LABEL: define float @powf_libcall_half_ninf_tail(
787 ; NOLIB-SAME: float [[X:%.*]]) {
788 ; NOLIB-NEXT: [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01)
789 ; NOLIB-NEXT: ret float [[RETVAL]]
791 %retval = tail call ninf float @powf(float %x, float 0.5)
795 define float @powf_libcall_half_ninf_tail_noerrno(float %x) {
796 ; ANY-LABEL: define float @powf_libcall_half_ninf_tail_noerrno(
797 ; ANY-SAME: float [[X:%.*]]) {
798 ; ANY-NEXT: [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]])
799 ; ANY-NEXT: [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRT]])
800 ; ANY-NEXT: ret float [[ABS]]
802 ; VC32-LABEL: define float @powf_libcall_half_ninf_tail_noerrno(
803 ; VC32-SAME: float [[X:%.*]]) {
804 ; VC32-NEXT: [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
805 ; VC32-NEXT: ret float [[RETVAL]]
807 ; VC51-LABEL: define float @powf_libcall_half_ninf_tail_noerrno(
808 ; VC51-SAME: float [[X:%.*]]) {
809 ; VC51-NEXT: [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
810 ; VC51-NEXT: ret float [[RETVAL]]
812 ; VC64-LABEL: define float @powf_libcall_half_ninf_tail_noerrno(
813 ; VC64-SAME: float [[X:%.*]]) {
814 ; VC64-NEXT: [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]])
815 ; VC64-NEXT: [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRT]])
816 ; VC64-NEXT: ret float [[ABS]]
818 ; VC83-LABEL: define float @powf_libcall_half_ninf_tail_noerrno(
819 ; VC83-SAME: float [[X:%.*]]) {
820 ; VC83-NEXT: [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float [[X]])
821 ; VC83-NEXT: [[ABS:%.*]] = tail call ninf float @llvm.fabs.f32(float [[SQRT]])
822 ; VC83-NEXT: ret float [[ABS]]
824 ; NOLIB-LABEL: define float @powf_libcall_half_ninf_tail_noerrno(
825 ; NOLIB-SAME: float [[X:%.*]]) {
826 ; NOLIB-NEXT: [[RETVAL:%.*]] = tail call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2]]
827 ; NOLIB-NEXT: ret float [[RETVAL]]
829 %retval = tail call ninf float @powf(float %x, float 0.5) #0
833 define float @powf_libcall_half_ninf_musttail(float %x, float %y) {
834 ; CHECK-LABEL: define float @powf_libcall_half_ninf_musttail(
835 ; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
836 ; CHECK-NEXT: [[RETVAL:%.*]] = musttail call ninf float @powf(float [[X]], float 5.000000e-01)
837 ; CHECK-NEXT: ret float [[RETVAL]]
839 %retval = musttail call ninf float @powf(float %x, float 0.5)
843 define float @powf_libcall_half_ninf_musttail_noerrno(float %x, float %y) {
844 ; CHECK-LABEL: define float @powf_libcall_half_ninf_musttail_noerrno(
845 ; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
846 ; CHECK-NEXT: [[RETVAL:%.*]] = musttail call ninf float @powf(float [[X]], float 5.000000e-01) #[[ATTR2:[0-9]+]]
847 ; CHECK-NEXT: ret float [[RETVAL]]
849 %retval = musttail call ninf float @powf(float %x, float 0.5) #0
853 ; Check pow(x, 0.5) where x may be -infinity does not call a library sqrt function.
855 define double @pow_libcall_half_no_FMF(double %x) {
856 ; CHECK-LABEL: define double @pow_libcall_half_no_FMF(
857 ; CHECK-SAME: double [[X:%.*]]) {
858 ; CHECK-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 5.000000e-01)
859 ; CHECK-NEXT: ret double [[RETVAL]]
861 %retval = call double @pow(double %x, double 0.5)
865 define double @pow_libcall_half_fromdomcondition(double %x) {
866 ; LIB-LABEL: define double @pow_libcall_half_fromdomcondition(
867 ; LIB-SAME: double [[X:%.*]]) {
868 ; LIB-NEXT: [[A:%.*]] = call double @llvm.fabs.f64(double [[X]])
869 ; LIB-NEXT: [[C:%.*]] = fcmp oeq double [[A]], 0x7FF0000000000000
870 ; LIB-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
872 ; LIB-NEXT: ret double 0.000000e+00
874 ; LIB-NEXT: [[SQRT:%.*]] = call double @sqrt(double [[X]])
875 ; LIB-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]])
876 ; LIB-NEXT: ret double [[ABS]]
878 ; NOLIB-LABEL: define double @pow_libcall_half_fromdomcondition(
879 ; NOLIB-SAME: double [[X:%.*]]) {
880 ; NOLIB-NEXT: [[A:%.*]] = call double @llvm.fabs.f64(double [[X]])
881 ; NOLIB-NEXT: [[C:%.*]] = fcmp oeq double [[A]], 0x7FF0000000000000
882 ; NOLIB-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
884 ; NOLIB-NEXT: ret double 0.000000e+00
886 ; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 5.000000e-01)
887 ; NOLIB-NEXT: ret double [[RETVAL]]
889 %a = call double @llvm.fabs.f64(double %x)
890 %c = fcmp oeq double %a, 0x7FF0000000000000
891 br i1 %c, label %then, label %else
897 %retval = call double @pow(double %x, double 0.5)
901 define double @pow_libcall_half_no_FMF_noerrno(double %x) {
902 ; LIB-LABEL: define double @pow_libcall_half_no_FMF_noerrno(
903 ; LIB-SAME: double [[X:%.*]]) {
904 ; LIB-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X]])
905 ; LIB-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]])
906 ; LIB-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000
907 ; LIB-NEXT: [[RETVAL:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]]
908 ; LIB-NEXT: ret double [[RETVAL]]
910 ; NOLIB-LABEL: define double @pow_libcall_half_no_FMF_noerrno(
911 ; NOLIB-SAME: double [[X:%.*]]) {
912 ; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 5.000000e-01) #[[ATTR2]]
913 ; NOLIB-NEXT: ret double [[RETVAL]]
915 %retval = call double @pow(double %x, double 0.5) #0
919 ; Check pow(-infinity, 0.5) -> +infinity.
921 define float @test_simplify9(float %x) {
922 ; CHECK-LABEL: define float @test_simplify9(
923 ; CHECK-SAME: float [[X:%.*]]) {
924 ; CHECK-NEXT: ret float 0x7FF0000000000000
926 %retval = call float @llvm.pow.f32(float 0xFFF0000000000000, float 0.5)
930 define double @test_simplify10(double %x) {
931 ; CHECK-LABEL: define double @test_simplify10(
932 ; CHECK-SAME: double [[X:%.*]]) {
933 ; CHECK-NEXT: ret double 0x7FF0000000000000
935 %retval = call double @llvm.pow.f64(double 0xFFF0000000000000, double 0.5)
939 ; Check pow(x, 1.0) -> x.
941 define float @test_simplify11(float %x) {
942 ; ANY-LABEL: define float @test_simplify11(
943 ; ANY-SAME: float [[X:%.*]]) {
944 ; ANY-NEXT: ret float [[X]]
946 ; VC32-LABEL: define float @test_simplify11(
947 ; VC32-SAME: float [[X:%.*]]) {
948 ; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00)
949 ; VC32-NEXT: ret float [[RETVAL]]
951 ; VC51-LABEL: define float @test_simplify11(
952 ; VC51-SAME: float [[X:%.*]]) {
953 ; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00)
954 ; VC51-NEXT: ret float [[RETVAL]]
956 ; VC64-LABEL: define float @test_simplify11(
957 ; VC64-SAME: float [[X:%.*]]) {
958 ; VC64-NEXT: ret float [[X]]
960 ; VC83-LABEL: define float @test_simplify11(
961 ; VC83-SAME: float [[X:%.*]]) {
962 ; VC83-NEXT: ret float [[X]]
964 ; NOLIB-LABEL: define float @test_simplify11(
965 ; NOLIB-SAME: float [[X:%.*]]) {
966 ; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00)
967 ; NOLIB-NEXT: ret float [[RETVAL]]
969 %retval = call float @powf(float %x, float 1.0)
973 define float @test_simplify11_noerrno(float %x) {
974 ; ANY-LABEL: define float @test_simplify11_noerrno(
975 ; ANY-SAME: float [[X:%.*]]) {
976 ; ANY-NEXT: ret float [[X]]
978 ; VC32-LABEL: define float @test_simplify11_noerrno(
979 ; VC32-SAME: float [[X:%.*]]) {
980 ; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00) #[[ATTR2]]
981 ; VC32-NEXT: ret float [[RETVAL]]
983 ; VC51-LABEL: define float @test_simplify11_noerrno(
984 ; VC51-SAME: float [[X:%.*]]) {
985 ; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00) #[[ATTR2]]
986 ; VC51-NEXT: ret float [[RETVAL]]
988 ; VC64-LABEL: define float @test_simplify11_noerrno(
989 ; VC64-SAME: float [[X:%.*]]) {
990 ; VC64-NEXT: ret float [[X]]
992 ; VC83-LABEL: define float @test_simplify11_noerrno(
993 ; VC83-SAME: float [[X:%.*]]) {
994 ; VC83-NEXT: ret float [[X]]
996 ; NOLIB-LABEL: define float @test_simplify11_noerrno(
997 ; NOLIB-SAME: float [[X:%.*]]) {
998 ; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00) #[[ATTR2]]
999 ; NOLIB-NEXT: ret float [[RETVAL]]
1001 %retval = call float @powf(float %x, float 1.0) #0
1005 define <2 x float> @test_simplify11v(<2 x float> %x) {
1006 ; CHECK-LABEL: define <2 x float> @test_simplify11v(
1007 ; CHECK-SAME: <2 x float> [[X:%.*]]) {
1008 ; CHECK-NEXT: ret <2 x float> [[X]]
1010 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 1.0, float 1.0>)
1011 ret <2 x float> %retval
1014 define double @test_simplify12(double %x) {
1015 ; LIB-LABEL: define double @test_simplify12(
1016 ; LIB-SAME: double [[X:%.*]]) {
1017 ; LIB-NEXT: ret double [[X]]
1019 ; NOLIB-LABEL: define double @test_simplify12(
1020 ; NOLIB-SAME: double [[X:%.*]]) {
1021 ; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 1.000000e+00)
1022 ; NOLIB-NEXT: ret double [[RETVAL]]
1024 %retval = call double @pow(double %x, double 1.0)
1028 define double @test_simplify12_noerrno(double %x) {
1029 ; LIB-LABEL: define double @test_simplify12_noerrno(
1030 ; LIB-SAME: double [[X:%.*]]) {
1031 ; LIB-NEXT: ret double [[X]]
1033 ; NOLIB-LABEL: define double @test_simplify12_noerrno(
1034 ; NOLIB-SAME: double [[X:%.*]]) {
1035 ; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 1.000000e+00) #[[ATTR2]]
1036 ; NOLIB-NEXT: ret double [[RETVAL]]
1038 %retval = call double @pow(double %x, double 1.0) #0
1042 define <2 x double> @test_simplify12v(<2 x double> %x) {
1043 ; CHECK-LABEL: define <2 x double> @test_simplify12v(
1044 ; CHECK-SAME: <2 x double> [[X:%.*]]) {
1045 ; CHECK-NEXT: ret <2 x double> [[X]]
1047 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 1.0, double 1.0>)
1048 ret <2 x double> %retval
1051 ; Check pow(x, 2.0) -> x*x.
1053 define float @pow2_strict(float %x) {
1054 ; ANY-LABEL: define float @pow2_strict(
1055 ; ANY-SAME: float [[X:%.*]]) {
1056 ; ANY-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1057 ; ANY-NEXT: ret float [[SQUARE]]
1059 ; VC32-LABEL: define float @pow2_strict(
1060 ; VC32-SAME: float [[X:%.*]]) {
1061 ; VC32-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00)
1062 ; VC32-NEXT: ret float [[R]]
1064 ; VC51-LABEL: define float @pow2_strict(
1065 ; VC51-SAME: float [[X:%.*]]) {
1066 ; VC51-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00)
1067 ; VC51-NEXT: ret float [[R]]
1069 ; VC64-LABEL: define float @pow2_strict(
1070 ; VC64-SAME: float [[X:%.*]]) {
1071 ; VC64-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1072 ; VC64-NEXT: ret float [[SQUARE]]
1074 ; VC83-LABEL: define float @pow2_strict(
1075 ; VC83-SAME: float [[X:%.*]]) {
1076 ; VC83-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1077 ; VC83-NEXT: ret float [[SQUARE]]
1079 ; NOLIB-LABEL: define float @pow2_strict(
1080 ; NOLIB-SAME: float [[X:%.*]]) {
1081 ; NOLIB-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00)
1082 ; NOLIB-NEXT: ret float [[R]]
1084 %r = call float @powf(float %x, float 2.0)
1088 define float @pow2_strict_noerrno(float %x) {
1089 ; ANY-LABEL: define float @pow2_strict_noerrno(
1090 ; ANY-SAME: float [[X:%.*]]) {
1091 ; ANY-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1092 ; ANY-NEXT: ret float [[SQUARE]]
1094 ; VC32-LABEL: define float @pow2_strict_noerrno(
1095 ; VC32-SAME: float [[X:%.*]]) {
1096 ; VC32-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1097 ; VC32-NEXT: ret float [[R]]
1099 ; VC51-LABEL: define float @pow2_strict_noerrno(
1100 ; VC51-SAME: float [[X:%.*]]) {
1101 ; VC51-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1102 ; VC51-NEXT: ret float [[R]]
1104 ; VC64-LABEL: define float @pow2_strict_noerrno(
1105 ; VC64-SAME: float [[X:%.*]]) {
1106 ; VC64-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1107 ; VC64-NEXT: ret float [[SQUARE]]
1109 ; VC83-LABEL: define float @pow2_strict_noerrno(
1110 ; VC83-SAME: float [[X:%.*]]) {
1111 ; VC83-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1112 ; VC83-NEXT: ret float [[SQUARE]]
1114 ; NOLIB-LABEL: define float @pow2_strict_noerrno(
1115 ; NOLIB-SAME: float [[X:%.*]]) {
1116 ; NOLIB-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1117 ; NOLIB-NEXT: ret float [[R]]
1119 %r = call float @powf(float %x, float 2.0) #0
1123 define <2 x float> @pow2_strictv(<2 x float> %x) {
1124 ; CHECK-LABEL: define <2 x float> @pow2_strictv(
1125 ; CHECK-SAME: <2 x float> [[X:%.*]]) {
1126 ; CHECK-NEXT: [[SQUARE:%.*]] = fmul <2 x float> [[X]], [[X]]
1127 ; CHECK-NEXT: ret <2 x float> [[SQUARE]]
1129 %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 2.0, float 2.0>)
1133 define double @pow2_double_strict(double %x) {
1134 ; LIB-LABEL: define double @pow2_double_strict(
1135 ; LIB-SAME: double [[X:%.*]]) {
1136 ; LIB-NEXT: [[SQUARE:%.*]] = fmul double [[X]], [[X]]
1137 ; LIB-NEXT: ret double [[SQUARE]]
1139 ; NOLIB-LABEL: define double @pow2_double_strict(
1140 ; NOLIB-SAME: double [[X:%.*]]) {
1141 ; NOLIB-NEXT: [[R:%.*]] = call double @pow(double [[X]], double 2.000000e+00)
1142 ; NOLIB-NEXT: ret double [[R]]
1144 %r = call double @pow(double %x, double 2.0)
1148 define double @pow2_double_strict_noerrno(double %x) {
1149 ; LIB-LABEL: define double @pow2_double_strict_noerrno(
1150 ; LIB-SAME: double [[X:%.*]]) {
1151 ; LIB-NEXT: [[SQUARE:%.*]] = fmul double [[X]], [[X]]
1152 ; LIB-NEXT: ret double [[SQUARE]]
1154 ; NOLIB-LABEL: define double @pow2_double_strict_noerrno(
1155 ; NOLIB-SAME: double [[X:%.*]]) {
1156 ; NOLIB-NEXT: [[R:%.*]] = call double @pow(double [[X]], double 2.000000e+00) #[[ATTR2]]
1157 ; NOLIB-NEXT: ret double [[R]]
1159 %r = call double @pow(double %x, double 2.0) #0
1163 define <2 x double> @pow2_double_strictv(<2 x double> %x) {
1164 ; CHECK-LABEL: define <2 x double> @pow2_double_strictv(
1165 ; CHECK-SAME: <2 x double> [[X:%.*]]) {
1166 ; CHECK-NEXT: [[SQUARE:%.*]] = fmul <2 x double> [[X]], [[X]]
1167 ; CHECK-NEXT: ret <2 x double> [[SQUARE]]
1169 %r = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 2.0, double 2.0>)
1173 ; Don't drop the FMF - PR35601 ( https://bugs.llvm.org/show_bug.cgi?id=35601 )
1175 define float @pow2_fast(float %x) {
1176 ; ANY-LABEL: define float @pow2_fast(
1177 ; ANY-SAME: float [[X:%.*]]) {
1178 ; ANY-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1179 ; ANY-NEXT: ret float [[SQUARE]]
1181 ; VC32-LABEL: define float @pow2_fast(
1182 ; VC32-SAME: float [[X:%.*]]) {
1183 ; VC32-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00)
1184 ; VC32-NEXT: ret float [[R]]
1186 ; VC51-LABEL: define float @pow2_fast(
1187 ; VC51-SAME: float [[X:%.*]]) {
1188 ; VC51-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00)
1189 ; VC51-NEXT: ret float [[R]]
1191 ; VC64-LABEL: define float @pow2_fast(
1192 ; VC64-SAME: float [[X:%.*]]) {
1193 ; VC64-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1194 ; VC64-NEXT: ret float [[SQUARE]]
1196 ; VC83-LABEL: define float @pow2_fast(
1197 ; VC83-SAME: float [[X:%.*]]) {
1198 ; VC83-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1199 ; VC83-NEXT: ret float [[SQUARE]]
1201 ; NOLIB-LABEL: define float @pow2_fast(
1202 ; NOLIB-SAME: float [[X:%.*]]) {
1203 ; NOLIB-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00)
1204 ; NOLIB-NEXT: ret float [[R]]
1206 %r = call fast float @powf(float %x, float 2.0)
1210 define float @pow2_fast_noerrno(float %x) {
1211 ; ANY-LABEL: define float @pow2_fast_noerrno(
1212 ; ANY-SAME: float [[X:%.*]]) {
1213 ; ANY-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1214 ; ANY-NEXT: ret float [[SQUARE]]
1216 ; VC32-LABEL: define float @pow2_fast_noerrno(
1217 ; VC32-SAME: float [[X:%.*]]) {
1218 ; VC32-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1219 ; VC32-NEXT: ret float [[R]]
1221 ; VC51-LABEL: define float @pow2_fast_noerrno(
1222 ; VC51-SAME: float [[X:%.*]]) {
1223 ; VC51-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1224 ; VC51-NEXT: ret float [[R]]
1226 ; VC64-LABEL: define float @pow2_fast_noerrno(
1227 ; VC64-SAME: float [[X:%.*]]) {
1228 ; VC64-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1229 ; VC64-NEXT: ret float [[SQUARE]]
1231 ; VC83-LABEL: define float @pow2_fast_noerrno(
1232 ; VC83-SAME: float [[X:%.*]]) {
1233 ; VC83-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1234 ; VC83-NEXT: ret float [[SQUARE]]
1236 ; NOLIB-LABEL: define float @pow2_fast_noerrno(
1237 ; NOLIB-SAME: float [[X:%.*]]) {
1238 ; NOLIB-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1239 ; NOLIB-NEXT: ret float [[R]]
1241 %r = call fast float @powf(float %x, float 2.0) #0
1245 ; Check pow(x, -1.0) -> 1.0/x.
1247 define float @pow_neg1_strict(float %x) {
1248 ; ANY-LABEL: define float @pow_neg1_strict(
1249 ; ANY-SAME: float [[X:%.*]]) {
1250 ; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1251 ; ANY-NEXT: ret float [[RECIPROCAL]]
1253 ; VC32-LABEL: define float @pow_neg1_strict(
1254 ; VC32-SAME: float [[X:%.*]]) {
1255 ; VC32-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00)
1256 ; VC32-NEXT: ret float [[R]]
1258 ; VC51-LABEL: define float @pow_neg1_strict(
1259 ; VC51-SAME: float [[X:%.*]]) {
1260 ; VC51-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00)
1261 ; VC51-NEXT: ret float [[R]]
1263 ; VC64-LABEL: define float @pow_neg1_strict(
1264 ; VC64-SAME: float [[X:%.*]]) {
1265 ; VC64-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1266 ; VC64-NEXT: ret float [[RECIPROCAL]]
1268 ; VC83-LABEL: define float @pow_neg1_strict(
1269 ; VC83-SAME: float [[X:%.*]]) {
1270 ; VC83-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1271 ; VC83-NEXT: ret float [[RECIPROCAL]]
1273 ; NOLIB-LABEL: define float @pow_neg1_strict(
1274 ; NOLIB-SAME: float [[X:%.*]]) {
1275 ; NOLIB-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00)
1276 ; NOLIB-NEXT: ret float [[R]]
1278 %r = call float @powf(float %x, float -1.0)
1282 define float @pow_neg1_strict_noerrno(float %x) {
1283 ; ANY-LABEL: define float @pow_neg1_strict_noerrno(
1284 ; ANY-SAME: float [[X:%.*]]) {
1285 ; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1286 ; ANY-NEXT: ret float [[RECIPROCAL]]
1288 ; VC32-LABEL: define float @pow_neg1_strict_noerrno(
1289 ; VC32-SAME: float [[X:%.*]]) {
1290 ; VC32-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00) #[[ATTR2]]
1291 ; VC32-NEXT: ret float [[R]]
1293 ; VC51-LABEL: define float @pow_neg1_strict_noerrno(
1294 ; VC51-SAME: float [[X:%.*]]) {
1295 ; VC51-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00) #[[ATTR2]]
1296 ; VC51-NEXT: ret float [[R]]
1298 ; VC64-LABEL: define float @pow_neg1_strict_noerrno(
1299 ; VC64-SAME: float [[X:%.*]]) {
1300 ; VC64-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1301 ; VC64-NEXT: ret float [[RECIPROCAL]]
1303 ; VC83-LABEL: define float @pow_neg1_strict_noerrno(
1304 ; VC83-SAME: float [[X:%.*]]) {
1305 ; VC83-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1306 ; VC83-NEXT: ret float [[RECIPROCAL]]
1308 ; NOLIB-LABEL: define float @pow_neg1_strict_noerrno(
1309 ; NOLIB-SAME: float [[X:%.*]]) {
1310 ; NOLIB-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00) #[[ATTR2]]
1311 ; NOLIB-NEXT: ret float [[R]]
1313 %r = call float @powf(float %x, float -1.0) #0
1317 define <2 x float> @pow_neg1_strictv(<2 x float> %x) {
1318 ; CHECK-LABEL: define <2 x float> @pow_neg1_strictv(
1319 ; CHECK-SAME: <2 x float> [[X:%.*]]) {
1320 ; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv <2 x float> splat (float 1.000000e+00), [[X]]
1321 ; CHECK-NEXT: ret <2 x float> [[RECIPROCAL]]
1323 %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float -1.0, float -1.0>)
1327 define double @pow_neg1_double_fast(double %x) {
1328 ; LIB-LABEL: define double @pow_neg1_double_fast(
1329 ; LIB-SAME: double [[X:%.*]]) {
1330 ; LIB-NEXT: [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[X]]
1331 ; LIB-NEXT: ret double [[RECIPROCAL]]
1333 ; NOLIB-LABEL: define double @pow_neg1_double_fast(
1334 ; NOLIB-SAME: double [[X:%.*]]) {
1335 ; NOLIB-NEXT: [[R:%.*]] = call fast double @pow(double [[X]], double -1.000000e+00)
1336 ; NOLIB-NEXT: ret double [[R]]
1338 %r = call fast double @pow(double %x, double -1.0)
1342 define double @pow_neg1_double_fast_noerrno(double %x) {
1343 ; LIB-LABEL: define double @pow_neg1_double_fast_noerrno(
1344 ; LIB-SAME: double [[X:%.*]]) {
1345 ; LIB-NEXT: [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[X]]
1346 ; LIB-NEXT: ret double [[RECIPROCAL]]
1348 ; NOLIB-LABEL: define double @pow_neg1_double_fast_noerrno(
1349 ; NOLIB-SAME: double [[X:%.*]]) {
1350 ; NOLIB-NEXT: [[R:%.*]] = call fast double @pow(double [[X]], double -1.000000e+00) #[[ATTR2]]
1351 ; NOLIB-NEXT: ret double [[R]]
1353 %r = call fast double @pow(double %x, double -1.0) #0
1357 define <2 x double> @pow_neg1_double_fastv(<2 x double> %x) {
1358 ; CHECK-LABEL: define <2 x double> @pow_neg1_double_fastv(
1359 ; CHECK-SAME: <2 x double> [[X:%.*]]) {
1360 ; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv fast <2 x double> splat (double 1.000000e+00), [[X]]
1361 ; CHECK-NEXT: ret <2 x double> [[RECIPROCAL]]
1363 %r = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double -1.0, double -1.0>)
1367 define double @pow_intrinsic_half_no_FMF(double %x) {
1368 ; CHECK-LABEL: define double @pow_intrinsic_half_no_FMF(
1369 ; CHECK-SAME: double [[X:%.*]]) {
1370 ; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X]])
1371 ; CHECK-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]])
1372 ; CHECK-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000
1373 ; CHECK-NEXT: [[RETVAL:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]]
1374 ; CHECK-NEXT: ret double [[RETVAL]]
1376 %retval = call double @llvm.pow.f64(double %x, double 0.5)
1380 ; Check pow(10.0, x) -> __exp10(x) on OS X 10.9+ and iOS 7.0+.
1382 define float @test_simplify18(float %x) {
1383 ; CHECK-EXP10-LABEL: define float @test_simplify18(
1384 ; CHECK-EXP10-SAME: float [[X:%.*]]) {
1385 ; CHECK-EXP10-NEXT: [[__EXP10F:%.*]] = call float @__exp10f(float [[X]])
1386 ; CHECK-EXP10-NEXT: ret float [[__EXP10F]]
1388 ; CHECK-NO-EXP10-LABEL: define float @test_simplify18(
1389 ; CHECK-NO-EXP10-SAME: float [[X:%.*]]) {
1390 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]])
1391 ; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]]
1393 %retval = call float @powf(float 10.0, float %x)
1397 define float @test_simplify18_noerrno(float %x) {
1398 ; CHECK-EXP10-LABEL: define float @test_simplify18_noerrno(
1399 ; CHECK-EXP10-SAME: float [[X:%.*]]) {
1400 ; CHECK-EXP10-NEXT: [[EXP10:%.*]] = call float @llvm.exp10.f32(float [[X]])
1401 ; CHECK-EXP10-NEXT: ret float [[EXP10]]
1403 ; CHECK-NO-EXP10-LABEL: define float @test_simplify18_noerrno(
1404 ; CHECK-NO-EXP10-SAME: float [[X:%.*]]) {
1405 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) #[[ATTR2]]
1406 ; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]]
1408 %retval = call float @powf(float 10.0, float %x) #0
1412 define double @test_simplify19(double %x) {
1413 ; CHECK-EXP10-LABEL: define double @test_simplify19(
1414 ; CHECK-EXP10-SAME: double [[X:%.*]]) {
1415 ; CHECK-EXP10-NEXT: [[__EXP10:%.*]] = call double @__exp10(double [[X]])
1416 ; CHECK-EXP10-NEXT: ret double [[__EXP10]]
1418 ; CHECK-NO-EXP10-LABEL: define double @test_simplify19(
1419 ; CHECK-NO-EXP10-SAME: double [[X:%.*]]) {
1420 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]])
1421 ; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]]
1423 %retval = call double @pow(double 10.0, double %x)
1427 define double @test_simplify19_noerrno(double %x) {
1428 ; CHECK-EXP10-LABEL: define double @test_simplify19_noerrno(
1429 ; CHECK-EXP10-SAME: double [[X:%.*]]) {
1430 ; CHECK-EXP10-NEXT: [[EXP10:%.*]] = call double @llvm.exp10.f64(double [[X]])
1431 ; CHECK-EXP10-NEXT: ret double [[EXP10]]
1433 ; CHECK-NO-EXP10-LABEL: define double @test_simplify19_noerrno(
1434 ; CHECK-NO-EXP10-SAME: double [[X:%.*]]) {
1435 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]]) #[[ATTR2]]
1436 ; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]]
1438 %retval = call double @pow(double 10.0, double %x) #0
1442 define float @test_libcall_powf_10_f32_noerrno(float %x) {
1443 ; CHECK-EXP10-LABEL: define float @test_libcall_powf_10_f32_noerrno(
1444 ; CHECK-EXP10-SAME: float [[X:%.*]]) {
1445 ; CHECK-EXP10-NEXT: [[__EXP10F:%.*]] = call float @llvm.exp10.f32(float [[X]])
1446 ; CHECK-EXP10-NEXT: ret float [[__EXP10F]]
1448 ; CHECK-NO-EXP10-LABEL: define float @test_libcall_powf_10_f32_noerrno(
1449 ; CHECK-NO-EXP10-SAME: float [[X:%.*]]) {
1450 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) #[[ATTR2]]
1451 ; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]]
1453 %retval = call float @powf(float 10.0, float %x) #0
1457 define double @test_libcall_pow_10_f64_noerrno(double %x) {
1458 ; CHECK-EXP10-LABEL: define double @test_libcall_pow_10_f64_noerrno(
1459 ; CHECK-EXP10-SAME: double [[X:%.*]]) {
1460 ; CHECK-EXP10-NEXT: [[__EXP10:%.*]] = call double @llvm.exp10.f64(double [[X]])
1461 ; CHECK-EXP10-NEXT: ret double [[__EXP10]]
1463 ; CHECK-NO-EXP10-LABEL: define double @test_libcall_pow_10_f64_noerrno(
1464 ; CHECK-NO-EXP10-SAME: double [[X:%.*]]) {
1465 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]]) #[[ATTR2]]
1466 ; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]]
1468 %retval = call double @pow(double 10.0, double %x) #0
1472 define half @test_pow_10_f16(half %x) {
1473 ; CHECK-LABEL: define half @test_pow_10_f16(
1474 ; CHECK-SAME: half [[X:%.*]]) {
1475 ; CHECK-NEXT: [[RETVAL:%.*]] = call half @llvm.pow.f16(half 0xH4900, half [[X]])
1476 ; CHECK-NEXT: ret half [[RETVAL]]
1478 %retval = call half @llvm.pow.f16(half 10.0, half %x)
1482 define float @test_pow_10_f32(float %x) {
1483 ; CHECK-EXP10-LABEL: define float @test_pow_10_f32(
1484 ; CHECK-EXP10-SAME: float [[X:%.*]]) {
1485 ; CHECK-EXP10-NEXT: [[__EXP10F:%.*]] = call float @llvm.exp10.f32(float [[X]])
1486 ; CHECK-EXP10-NEXT: ret float [[__EXP10F]]
1488 ; CHECK-NO-EXP10-LABEL: define float @test_pow_10_f32(
1489 ; CHECK-NO-EXP10-SAME: float [[X:%.*]]) {
1490 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @llvm.pow.f32(float 1.000000e+01, float [[X]])
1491 ; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]]
1493 %retval = call float @llvm.pow.f32(float 10.0, float %x)
1497 define double @test_pow_10_f64(double %x) {
1498 ; CHECK-EXP10-LABEL: define double @test_pow_10_f64(
1499 ; CHECK-EXP10-SAME: double [[X:%.*]]) {
1500 ; CHECK-EXP10-NEXT: [[__EXP10:%.*]] = call double @llvm.exp10.f64(double [[X]])
1501 ; CHECK-EXP10-NEXT: ret double [[__EXP10]]
1503 ; CHECK-NO-EXP10-LABEL: define double @test_pow_10_f64(
1504 ; CHECK-NO-EXP10-SAME: double [[X:%.*]]) {
1505 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @llvm.pow.f64(double 1.000000e+01, double [[X]])
1506 ; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]]
1508 %retval = call double @llvm.pow.f64(double 10.0, double %x)
1512 define fp128 @test_pow_10_fp128(fp128 %x) {
1513 ; CHECK-LABEL: define fp128 @test_pow_10_fp128(
1514 ; CHECK-SAME: fp128 [[X:%.*]]) {
1515 ; CHECK-NEXT: [[RETVAL:%.*]] = call fp128 @llvm.pow.f128(fp128 0xL00000000000000004002400000000000, fp128 [[X]])
1516 ; CHECK-NEXT: ret fp128 [[RETVAL]]
1518 %ten = fpext double 10.0 to fp128
1519 %retval = call fp128 @llvm.pow.fp128(fp128 %ten, fp128 %x)
1523 define bfloat @test_pow_10_bf16(bfloat %x) {
1524 ; CHECK-LABEL: define bfloat @test_pow_10_bf16(
1525 ; CHECK-SAME: bfloat [[X:%.*]]) {
1526 ; CHECK-NEXT: [[RETVAL:%.*]] = call bfloat @llvm.pow.bf16(bfloat 0xR4120, bfloat [[X]])
1527 ; CHECK-NEXT: ret bfloat [[RETVAL]]
1529 %retval = call bfloat @llvm.pow.bf16(bfloat 10.0, bfloat %x)
1533 define <2 x half> @test_pow_10_v2f16(<2 x half> %x) {
1534 ; CHECK-LABEL: define <2 x half> @test_pow_10_v2f16(
1535 ; CHECK-SAME: <2 x half> [[X:%.*]]) {
1536 ; CHECK-NEXT: [[RETVAL:%.*]] = call <2 x half> @llvm.pow.v2f16(<2 x half> splat (half 0xH4900), <2 x half> [[X]])
1537 ; CHECK-NEXT: ret <2 x half> [[RETVAL]]
1539 %retval = call <2 x half> @llvm.pow.v2f16(<2 x half> <half 10.0, half 10.0>, <2 x half> %x)
1540 ret <2 x half> %retval
1543 define <2 x float> @test_pow_10_v2f32(<2 x float> %x) {
1544 ; CHECK-LABEL: define <2 x float> @test_pow_10_v2f32(
1545 ; CHECK-SAME: <2 x float> [[X:%.*]]) {
1546 ; CHECK-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 1.000000e+01), <2 x float> [[X]])
1547 ; CHECK-NEXT: ret <2 x float> [[RETVAL]]
1549 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 10.0, float 10.0>, <2 x float> %x)
1550 ret <2 x float> %retval
1553 define <2 x double> @test_pow_10_v2f64(<2 x double> %x) {
1554 ; CHECK-LABEL: define <2 x double> @test_pow_10_v2f64(
1555 ; CHECK-SAME: <2 x double> [[X:%.*]]) {
1556 ; CHECK-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 1.000000e+01), <2 x double> [[X]])
1557 ; CHECK-NEXT: ret <2 x double> [[RETVAL]]
1559 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 10.0, double 10.0>, <2 x double> %x)
1560 ret <2 x double> %retval
1563 define <2 x bfloat> @test_pow_10_v2bf16(<2 x bfloat> %x) {
1564 ; CHECK-LABEL: define <2 x bfloat> @test_pow_10_v2bf16(
1565 ; CHECK-SAME: <2 x bfloat> [[X:%.*]]) {
1566 ; CHECK-NEXT: [[RETVAL:%.*]] = call <2 x bfloat> @llvm.pow.v2bf16(<2 x bfloat> splat (bfloat 0xR4120), <2 x bfloat> [[X]])
1567 ; CHECK-NEXT: ret <2 x bfloat> [[RETVAL]]
1569 %retval = call <2 x bfloat> @llvm.pow.v2bf16(<2 x bfloat> <bfloat 10.0, bfloat 10.0>, <2 x bfloat> %x)
1570 ret <2 x bfloat> %retval
1573 attributes #0 = { nounwind memory(none) }