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> <float 1.000000e+00, 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> <double 1.000000e+00, 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> <float 2.000000e+00, 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> <float 2.000000e+00, 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> <float 2.000000e+00, 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> <float 2.000000e+00, 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]], <double 2.000000e+00, 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> <double 4.000000e+00, 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> <double 4.000000e+00, 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> <double 4.000000e+00, 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> <double 4.000000e+00, 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> <double 2.000000e+00, 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> <double 2.000000e+00, 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> <double 2.000000e+00, 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> <double 2.000000e+00, 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> <float 5.000000e-01, 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> <float 5.000000e-01, 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> <float 5.000000e-01, 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> <float 5.000000e-01, 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> <float 1.000000e+00, 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> <double 1.000000e+00, 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_no_FMF_noerrno(double %x) {
866 ; LIB-LABEL: define double @pow_libcall_half_no_FMF_noerrno(
867 ; LIB-SAME: double [[X:%.*]]) {
868 ; LIB-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X]])
869 ; LIB-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]])
870 ; LIB-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000
871 ; LIB-NEXT: [[RETVAL:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]]
872 ; LIB-NEXT: ret double [[RETVAL]]
874 ; NOLIB-LABEL: define double @pow_libcall_half_no_FMF_noerrno(
875 ; NOLIB-SAME: double [[X:%.*]]) {
876 ; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 5.000000e-01) #[[ATTR2]]
877 ; NOLIB-NEXT: ret double [[RETVAL]]
879 %retval = call double @pow(double %x, double 0.5) #0
883 ; Check pow(-infinity, 0.5) -> +infinity.
885 define float @test_simplify9(float %x) {
886 ; CHECK-LABEL: define float @test_simplify9(
887 ; CHECK-SAME: float [[X:%.*]]) {
888 ; CHECK-NEXT: ret float 0x7FF0000000000000
890 %retval = call float @llvm.pow.f32(float 0xFFF0000000000000, float 0.5)
894 define double @test_simplify10(double %x) {
895 ; CHECK-LABEL: define double @test_simplify10(
896 ; CHECK-SAME: double [[X:%.*]]) {
897 ; CHECK-NEXT: ret double 0x7FF0000000000000
899 %retval = call double @llvm.pow.f64(double 0xFFF0000000000000, double 0.5)
903 ; Check pow(x, 1.0) -> x.
905 define float @test_simplify11(float %x) {
906 ; ANY-LABEL: define float @test_simplify11(
907 ; ANY-SAME: float [[X:%.*]]) {
908 ; ANY-NEXT: ret float [[X]]
910 ; VC32-LABEL: define float @test_simplify11(
911 ; VC32-SAME: float [[X:%.*]]) {
912 ; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00)
913 ; VC32-NEXT: ret float [[RETVAL]]
915 ; VC51-LABEL: define float @test_simplify11(
916 ; VC51-SAME: float [[X:%.*]]) {
917 ; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00)
918 ; VC51-NEXT: ret float [[RETVAL]]
920 ; VC64-LABEL: define float @test_simplify11(
921 ; VC64-SAME: float [[X:%.*]]) {
922 ; VC64-NEXT: ret float [[X]]
924 ; VC83-LABEL: define float @test_simplify11(
925 ; VC83-SAME: float [[X:%.*]]) {
926 ; VC83-NEXT: ret float [[X]]
928 ; NOLIB-LABEL: define float @test_simplify11(
929 ; NOLIB-SAME: float [[X:%.*]]) {
930 ; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00)
931 ; NOLIB-NEXT: ret float [[RETVAL]]
933 %retval = call float @powf(float %x, float 1.0)
937 define float @test_simplify11_noerrno(float %x) {
938 ; ANY-LABEL: define float @test_simplify11_noerrno(
939 ; ANY-SAME: float [[X:%.*]]) {
940 ; ANY-NEXT: ret float [[X]]
942 ; VC32-LABEL: define float @test_simplify11_noerrno(
943 ; VC32-SAME: float [[X:%.*]]) {
944 ; VC32-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00) #[[ATTR2]]
945 ; VC32-NEXT: ret float [[RETVAL]]
947 ; VC51-LABEL: define float @test_simplify11_noerrno(
948 ; VC51-SAME: float [[X:%.*]]) {
949 ; VC51-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00) #[[ATTR2]]
950 ; VC51-NEXT: ret float [[RETVAL]]
952 ; VC64-LABEL: define float @test_simplify11_noerrno(
953 ; VC64-SAME: float [[X:%.*]]) {
954 ; VC64-NEXT: ret float [[X]]
956 ; VC83-LABEL: define float @test_simplify11_noerrno(
957 ; VC83-SAME: float [[X:%.*]]) {
958 ; VC83-NEXT: ret float [[X]]
960 ; NOLIB-LABEL: define float @test_simplify11_noerrno(
961 ; NOLIB-SAME: float [[X:%.*]]) {
962 ; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X]], float 1.000000e+00) #[[ATTR2]]
963 ; NOLIB-NEXT: ret float [[RETVAL]]
965 %retval = call float @powf(float %x, float 1.0) #0
969 define <2 x float> @test_simplify11v(<2 x float> %x) {
970 ; CHECK-LABEL: define <2 x float> @test_simplify11v(
971 ; CHECK-SAME: <2 x float> [[X:%.*]]) {
972 ; CHECK-NEXT: ret <2 x float> [[X]]
974 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 1.0, float 1.0>)
975 ret <2 x float> %retval
978 define double @test_simplify12(double %x) {
979 ; LIB-LABEL: define double @test_simplify12(
980 ; LIB-SAME: double [[X:%.*]]) {
981 ; LIB-NEXT: ret double [[X]]
983 ; NOLIB-LABEL: define double @test_simplify12(
984 ; NOLIB-SAME: double [[X:%.*]]) {
985 ; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 1.000000e+00)
986 ; NOLIB-NEXT: ret double [[RETVAL]]
988 %retval = call double @pow(double %x, double 1.0)
992 define double @test_simplify12_noerrno(double %x) {
993 ; LIB-LABEL: define double @test_simplify12_noerrno(
994 ; LIB-SAME: double [[X:%.*]]) {
995 ; LIB-NEXT: ret double [[X]]
997 ; NOLIB-LABEL: define double @test_simplify12_noerrno(
998 ; NOLIB-SAME: double [[X:%.*]]) {
999 ; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X]], double 1.000000e+00) #[[ATTR2]]
1000 ; NOLIB-NEXT: ret double [[RETVAL]]
1002 %retval = call double @pow(double %x, double 1.0) #0
1006 define <2 x double> @test_simplify12v(<2 x double> %x) {
1007 ; CHECK-LABEL: define <2 x double> @test_simplify12v(
1008 ; CHECK-SAME: <2 x double> [[X:%.*]]) {
1009 ; CHECK-NEXT: ret <2 x double> [[X]]
1011 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 1.0, double 1.0>)
1012 ret <2 x double> %retval
1015 ; Check pow(x, 2.0) -> x*x.
1017 define float @pow2_strict(float %x) {
1018 ; ANY-LABEL: define float @pow2_strict(
1019 ; ANY-SAME: float [[X:%.*]]) {
1020 ; ANY-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1021 ; ANY-NEXT: ret float [[SQUARE]]
1023 ; VC32-LABEL: define float @pow2_strict(
1024 ; VC32-SAME: float [[X:%.*]]) {
1025 ; VC32-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00)
1026 ; VC32-NEXT: ret float [[R]]
1028 ; VC51-LABEL: define float @pow2_strict(
1029 ; VC51-SAME: float [[X:%.*]]) {
1030 ; VC51-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00)
1031 ; VC51-NEXT: ret float [[R]]
1033 ; VC64-LABEL: define float @pow2_strict(
1034 ; VC64-SAME: float [[X:%.*]]) {
1035 ; VC64-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1036 ; VC64-NEXT: ret float [[SQUARE]]
1038 ; VC83-LABEL: define float @pow2_strict(
1039 ; VC83-SAME: float [[X:%.*]]) {
1040 ; VC83-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1041 ; VC83-NEXT: ret float [[SQUARE]]
1043 ; NOLIB-LABEL: define float @pow2_strict(
1044 ; NOLIB-SAME: float [[X:%.*]]) {
1045 ; NOLIB-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00)
1046 ; NOLIB-NEXT: ret float [[R]]
1048 %r = call float @powf(float %x, float 2.0)
1052 define float @pow2_strict_noerrno(float %x) {
1053 ; ANY-LABEL: define float @pow2_strict_noerrno(
1054 ; ANY-SAME: float [[X:%.*]]) {
1055 ; ANY-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1056 ; ANY-NEXT: ret float [[SQUARE]]
1058 ; VC32-LABEL: define float @pow2_strict_noerrno(
1059 ; VC32-SAME: float [[X:%.*]]) {
1060 ; VC32-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1061 ; VC32-NEXT: ret float [[R]]
1063 ; VC51-LABEL: define float @pow2_strict_noerrno(
1064 ; VC51-SAME: float [[X:%.*]]) {
1065 ; VC51-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1066 ; VC51-NEXT: ret float [[R]]
1068 ; VC64-LABEL: define float @pow2_strict_noerrno(
1069 ; VC64-SAME: float [[X:%.*]]) {
1070 ; VC64-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1071 ; VC64-NEXT: ret float [[SQUARE]]
1073 ; VC83-LABEL: define float @pow2_strict_noerrno(
1074 ; VC83-SAME: float [[X:%.*]]) {
1075 ; VC83-NEXT: [[SQUARE:%.*]] = fmul float [[X]], [[X]]
1076 ; VC83-NEXT: ret float [[SQUARE]]
1078 ; NOLIB-LABEL: define float @pow2_strict_noerrno(
1079 ; NOLIB-SAME: float [[X:%.*]]) {
1080 ; NOLIB-NEXT: [[R:%.*]] = call float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1081 ; NOLIB-NEXT: ret float [[R]]
1083 %r = call float @powf(float %x, float 2.0) #0
1087 define <2 x float> @pow2_strictv(<2 x float> %x) {
1088 ; CHECK-LABEL: define <2 x float> @pow2_strictv(
1089 ; CHECK-SAME: <2 x float> [[X:%.*]]) {
1090 ; CHECK-NEXT: [[SQUARE:%.*]] = fmul <2 x float> [[X]], [[X]]
1091 ; CHECK-NEXT: ret <2 x float> [[SQUARE]]
1093 %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 2.0, float 2.0>)
1097 define double @pow2_double_strict(double %x) {
1098 ; LIB-LABEL: define double @pow2_double_strict(
1099 ; LIB-SAME: double [[X:%.*]]) {
1100 ; LIB-NEXT: [[SQUARE:%.*]] = fmul double [[X]], [[X]]
1101 ; LIB-NEXT: ret double [[SQUARE]]
1103 ; NOLIB-LABEL: define double @pow2_double_strict(
1104 ; NOLIB-SAME: double [[X:%.*]]) {
1105 ; NOLIB-NEXT: [[R:%.*]] = call double @pow(double [[X]], double 2.000000e+00)
1106 ; NOLIB-NEXT: ret double [[R]]
1108 %r = call double @pow(double %x, double 2.0)
1112 define double @pow2_double_strict_noerrno(double %x) {
1113 ; LIB-LABEL: define double @pow2_double_strict_noerrno(
1114 ; LIB-SAME: double [[X:%.*]]) {
1115 ; LIB-NEXT: [[SQUARE:%.*]] = fmul double [[X]], [[X]]
1116 ; LIB-NEXT: ret double [[SQUARE]]
1118 ; NOLIB-LABEL: define double @pow2_double_strict_noerrno(
1119 ; NOLIB-SAME: double [[X:%.*]]) {
1120 ; NOLIB-NEXT: [[R:%.*]] = call double @pow(double [[X]], double 2.000000e+00) #[[ATTR2]]
1121 ; NOLIB-NEXT: ret double [[R]]
1123 %r = call double @pow(double %x, double 2.0) #0
1127 define <2 x double> @pow2_double_strictv(<2 x double> %x) {
1128 ; CHECK-LABEL: define <2 x double> @pow2_double_strictv(
1129 ; CHECK-SAME: <2 x double> [[X:%.*]]) {
1130 ; CHECK-NEXT: [[SQUARE:%.*]] = fmul <2 x double> [[X]], [[X]]
1131 ; CHECK-NEXT: ret <2 x double> [[SQUARE]]
1133 %r = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 2.0, double 2.0>)
1137 ; Don't drop the FMF - PR35601 ( https://bugs.llvm.org/show_bug.cgi?id=35601 )
1139 define float @pow2_fast(float %x) {
1140 ; ANY-LABEL: define float @pow2_fast(
1141 ; ANY-SAME: float [[X:%.*]]) {
1142 ; ANY-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1143 ; ANY-NEXT: ret float [[SQUARE]]
1145 ; VC32-LABEL: define float @pow2_fast(
1146 ; VC32-SAME: float [[X:%.*]]) {
1147 ; VC32-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00)
1148 ; VC32-NEXT: ret float [[R]]
1150 ; VC51-LABEL: define float @pow2_fast(
1151 ; VC51-SAME: float [[X:%.*]]) {
1152 ; VC51-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00)
1153 ; VC51-NEXT: ret float [[R]]
1155 ; VC64-LABEL: define float @pow2_fast(
1156 ; VC64-SAME: float [[X:%.*]]) {
1157 ; VC64-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1158 ; VC64-NEXT: ret float [[SQUARE]]
1160 ; VC83-LABEL: define float @pow2_fast(
1161 ; VC83-SAME: float [[X:%.*]]) {
1162 ; VC83-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1163 ; VC83-NEXT: ret float [[SQUARE]]
1165 ; NOLIB-LABEL: define float @pow2_fast(
1166 ; NOLIB-SAME: float [[X:%.*]]) {
1167 ; NOLIB-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00)
1168 ; NOLIB-NEXT: ret float [[R]]
1170 %r = call fast float @powf(float %x, float 2.0)
1174 define float @pow2_fast_noerrno(float %x) {
1175 ; ANY-LABEL: define float @pow2_fast_noerrno(
1176 ; ANY-SAME: float [[X:%.*]]) {
1177 ; ANY-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1178 ; ANY-NEXT: ret float [[SQUARE]]
1180 ; VC32-LABEL: define float @pow2_fast_noerrno(
1181 ; VC32-SAME: float [[X:%.*]]) {
1182 ; VC32-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1183 ; VC32-NEXT: ret float [[R]]
1185 ; VC51-LABEL: define float @pow2_fast_noerrno(
1186 ; VC51-SAME: float [[X:%.*]]) {
1187 ; VC51-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1188 ; VC51-NEXT: ret float [[R]]
1190 ; VC64-LABEL: define float @pow2_fast_noerrno(
1191 ; VC64-SAME: float [[X:%.*]]) {
1192 ; VC64-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1193 ; VC64-NEXT: ret float [[SQUARE]]
1195 ; VC83-LABEL: define float @pow2_fast_noerrno(
1196 ; VC83-SAME: float [[X:%.*]]) {
1197 ; VC83-NEXT: [[SQUARE:%.*]] = fmul fast float [[X]], [[X]]
1198 ; VC83-NEXT: ret float [[SQUARE]]
1200 ; NOLIB-LABEL: define float @pow2_fast_noerrno(
1201 ; NOLIB-SAME: float [[X:%.*]]) {
1202 ; NOLIB-NEXT: [[R:%.*]] = call fast float @powf(float [[X]], float 2.000000e+00) #[[ATTR2]]
1203 ; NOLIB-NEXT: ret float [[R]]
1205 %r = call fast float @powf(float %x, float 2.0) #0
1209 ; Check pow(x, -1.0) -> 1.0/x.
1211 define float @pow_neg1_strict(float %x) {
1212 ; ANY-LABEL: define float @pow_neg1_strict(
1213 ; ANY-SAME: float [[X:%.*]]) {
1214 ; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1215 ; ANY-NEXT: ret float [[RECIPROCAL]]
1217 ; VC32-LABEL: define float @pow_neg1_strict(
1218 ; VC32-SAME: float [[X:%.*]]) {
1219 ; VC32-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00)
1220 ; VC32-NEXT: ret float [[R]]
1222 ; VC51-LABEL: define float @pow_neg1_strict(
1223 ; VC51-SAME: float [[X:%.*]]) {
1224 ; VC51-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00)
1225 ; VC51-NEXT: ret float [[R]]
1227 ; VC64-LABEL: define float @pow_neg1_strict(
1228 ; VC64-SAME: float [[X:%.*]]) {
1229 ; VC64-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1230 ; VC64-NEXT: ret float [[RECIPROCAL]]
1232 ; VC83-LABEL: define float @pow_neg1_strict(
1233 ; VC83-SAME: float [[X:%.*]]) {
1234 ; VC83-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1235 ; VC83-NEXT: ret float [[RECIPROCAL]]
1237 ; NOLIB-LABEL: define float @pow_neg1_strict(
1238 ; NOLIB-SAME: float [[X:%.*]]) {
1239 ; NOLIB-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00)
1240 ; NOLIB-NEXT: ret float [[R]]
1242 %r = call float @powf(float %x, float -1.0)
1246 define float @pow_neg1_strict_noerrno(float %x) {
1247 ; ANY-LABEL: define float @pow_neg1_strict_noerrno(
1248 ; ANY-SAME: float [[X:%.*]]) {
1249 ; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1250 ; ANY-NEXT: ret float [[RECIPROCAL]]
1252 ; VC32-LABEL: define float @pow_neg1_strict_noerrno(
1253 ; VC32-SAME: float [[X:%.*]]) {
1254 ; VC32-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00) #[[ATTR2]]
1255 ; VC32-NEXT: ret float [[R]]
1257 ; VC51-LABEL: define float @pow_neg1_strict_noerrno(
1258 ; VC51-SAME: float [[X:%.*]]) {
1259 ; VC51-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00) #[[ATTR2]]
1260 ; VC51-NEXT: ret float [[R]]
1262 ; VC64-LABEL: define float @pow_neg1_strict_noerrno(
1263 ; VC64-SAME: float [[X:%.*]]) {
1264 ; VC64-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1265 ; VC64-NEXT: ret float [[RECIPROCAL]]
1267 ; VC83-LABEL: define float @pow_neg1_strict_noerrno(
1268 ; VC83-SAME: float [[X:%.*]]) {
1269 ; VC83-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X]]
1270 ; VC83-NEXT: ret float [[RECIPROCAL]]
1272 ; NOLIB-LABEL: define float @pow_neg1_strict_noerrno(
1273 ; NOLIB-SAME: float [[X:%.*]]) {
1274 ; NOLIB-NEXT: [[R:%.*]] = call float @powf(float [[X]], float -1.000000e+00) #[[ATTR2]]
1275 ; NOLIB-NEXT: ret float [[R]]
1277 %r = call float @powf(float %x, float -1.0) #0
1281 define <2 x float> @pow_neg1_strictv(<2 x float> %x) {
1282 ; CHECK-LABEL: define <2 x float> @pow_neg1_strictv(
1283 ; CHECK-SAME: <2 x float> [[X:%.*]]) {
1284 ; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, [[X]]
1285 ; CHECK-NEXT: ret <2 x float> [[RECIPROCAL]]
1287 %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float -1.0, float -1.0>)
1291 define double @pow_neg1_double_fast(double %x) {
1292 ; LIB-LABEL: define double @pow_neg1_double_fast(
1293 ; LIB-SAME: double [[X:%.*]]) {
1294 ; LIB-NEXT: [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[X]]
1295 ; LIB-NEXT: ret double [[RECIPROCAL]]
1297 ; NOLIB-LABEL: define double @pow_neg1_double_fast(
1298 ; NOLIB-SAME: double [[X:%.*]]) {
1299 ; NOLIB-NEXT: [[R:%.*]] = call fast double @pow(double [[X]], double -1.000000e+00)
1300 ; NOLIB-NEXT: ret double [[R]]
1302 %r = call fast double @pow(double %x, double -1.0)
1306 define double @pow_neg1_double_fast_noerrno(double %x) {
1307 ; LIB-LABEL: define double @pow_neg1_double_fast_noerrno(
1308 ; LIB-SAME: double [[X:%.*]]) {
1309 ; LIB-NEXT: [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[X]]
1310 ; LIB-NEXT: ret double [[RECIPROCAL]]
1312 ; NOLIB-LABEL: define double @pow_neg1_double_fast_noerrno(
1313 ; NOLIB-SAME: double [[X:%.*]]) {
1314 ; NOLIB-NEXT: [[R:%.*]] = call fast double @pow(double [[X]], double -1.000000e+00) #[[ATTR2]]
1315 ; NOLIB-NEXT: ret double [[R]]
1317 %r = call fast double @pow(double %x, double -1.0) #0
1321 define <2 x double> @pow_neg1_double_fastv(<2 x double> %x) {
1322 ; CHECK-LABEL: define <2 x double> @pow_neg1_double_fastv(
1323 ; CHECK-SAME: <2 x double> [[X:%.*]]) {
1324 ; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv fast <2 x double> <double 1.000000e+00, double 1.000000e+00>, [[X]]
1325 ; CHECK-NEXT: ret <2 x double> [[RECIPROCAL]]
1327 %r = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double -1.0, double -1.0>)
1331 define double @pow_intrinsic_half_no_FMF(double %x) {
1332 ; CHECK-LABEL: define double @pow_intrinsic_half_no_FMF(
1333 ; CHECK-SAME: double [[X:%.*]]) {
1334 ; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X]])
1335 ; CHECK-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]])
1336 ; CHECK-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000
1337 ; CHECK-NEXT: [[RETVAL:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]]
1338 ; CHECK-NEXT: ret double [[RETVAL]]
1340 %retval = call double @llvm.pow.f64(double %x, double 0.5)
1344 ; Check pow(10.0, x) -> __exp10(x) on OS X 10.9+ and iOS 7.0+.
1346 define float @test_simplify18(float %x) {
1347 ; CHECK-EXP10-LABEL: define float @test_simplify18(
1348 ; CHECK-EXP10-SAME: float [[X:%.*]]) {
1349 ; CHECK-EXP10-NEXT: [[__EXP10F:%.*]] = call float @__exp10f(float [[X]])
1350 ; CHECK-EXP10-NEXT: ret float [[__EXP10F]]
1352 ; CHECK-NO-EXP10-LABEL: define float @test_simplify18(
1353 ; CHECK-NO-EXP10-SAME: float [[X:%.*]]) {
1354 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]])
1355 ; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]]
1357 %retval = call float @powf(float 10.0, float %x)
1361 define float @test_simplify18_noerrno(float %x) {
1362 ; CHECK-EXP10-LABEL: define float @test_simplify18_noerrno(
1363 ; CHECK-EXP10-SAME: float [[X:%.*]]) {
1364 ; CHECK-EXP10-NEXT: [[EXP10:%.*]] = call float @llvm.exp10.f32(float [[X]])
1365 ; CHECK-EXP10-NEXT: ret float [[EXP10]]
1367 ; CHECK-NO-EXP10-LABEL: define float @test_simplify18_noerrno(
1368 ; CHECK-NO-EXP10-SAME: float [[X:%.*]]) {
1369 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) #[[ATTR2]]
1370 ; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]]
1372 %retval = call float @powf(float 10.0, float %x) #0
1376 define double @test_simplify19(double %x) {
1377 ; CHECK-EXP10-LABEL: define double @test_simplify19(
1378 ; CHECK-EXP10-SAME: double [[X:%.*]]) {
1379 ; CHECK-EXP10-NEXT: [[__EXP10:%.*]] = call double @__exp10(double [[X]])
1380 ; CHECK-EXP10-NEXT: ret double [[__EXP10]]
1382 ; CHECK-NO-EXP10-LABEL: define double @test_simplify19(
1383 ; CHECK-NO-EXP10-SAME: double [[X:%.*]]) {
1384 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]])
1385 ; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]]
1387 %retval = call double @pow(double 10.0, double %x)
1391 define double @test_simplify19_noerrno(double %x) {
1392 ; CHECK-EXP10-LABEL: define double @test_simplify19_noerrno(
1393 ; CHECK-EXP10-SAME: double [[X:%.*]]) {
1394 ; CHECK-EXP10-NEXT: [[EXP10:%.*]] = call double @llvm.exp10.f64(double [[X]])
1395 ; CHECK-EXP10-NEXT: ret double [[EXP10]]
1397 ; CHECK-NO-EXP10-LABEL: define double @test_simplify19_noerrno(
1398 ; CHECK-NO-EXP10-SAME: double [[X:%.*]]) {
1399 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]]) #[[ATTR2]]
1400 ; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]]
1402 %retval = call double @pow(double 10.0, double %x) #0
1406 define float @test_libcall_powf_10_f32_noerrno(float %x) {
1407 ; CHECK-EXP10-LABEL: define float @test_libcall_powf_10_f32_noerrno(
1408 ; CHECK-EXP10-SAME: float [[X:%.*]]) {
1409 ; CHECK-EXP10-NEXT: [[__EXP10F:%.*]] = call float @llvm.exp10.f32(float [[X]])
1410 ; CHECK-EXP10-NEXT: ret float [[__EXP10F]]
1412 ; CHECK-NO-EXP10-LABEL: define float @test_libcall_powf_10_f32_noerrno(
1413 ; CHECK-NO-EXP10-SAME: float [[X:%.*]]) {
1414 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+01, float [[X]]) #[[ATTR2]]
1415 ; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]]
1417 %retval = call float @powf(float 10.0, float %x) #0
1421 define double @test_libcall_pow_10_f64_noerrno(double %x) {
1422 ; CHECK-EXP10-LABEL: define double @test_libcall_pow_10_f64_noerrno(
1423 ; CHECK-EXP10-SAME: double [[X:%.*]]) {
1424 ; CHECK-EXP10-NEXT: [[__EXP10:%.*]] = call double @llvm.exp10.f64(double [[X]])
1425 ; CHECK-EXP10-NEXT: ret double [[__EXP10]]
1427 ; CHECK-NO-EXP10-LABEL: define double @test_libcall_pow_10_f64_noerrno(
1428 ; CHECK-NO-EXP10-SAME: double [[X:%.*]]) {
1429 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+01, double [[X]]) #[[ATTR2]]
1430 ; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]]
1432 %retval = call double @pow(double 10.0, double %x) #0
1436 define half @test_pow_10_f16(half %x) {
1437 ; CHECK-LABEL: define half @test_pow_10_f16(
1438 ; CHECK-SAME: half [[X:%.*]]) {
1439 ; CHECK-NEXT: [[RETVAL:%.*]] = call half @llvm.pow.f16(half 0xH4900, half [[X]])
1440 ; CHECK-NEXT: ret half [[RETVAL]]
1442 %retval = call half @llvm.pow.f16(half 10.0, half %x)
1446 define float @test_pow_10_f32(float %x) {
1447 ; CHECK-EXP10-LABEL: define float @test_pow_10_f32(
1448 ; CHECK-EXP10-SAME: float [[X:%.*]]) {
1449 ; CHECK-EXP10-NEXT: [[__EXP10F:%.*]] = call float @llvm.exp10.f32(float [[X]])
1450 ; CHECK-EXP10-NEXT: ret float [[__EXP10F]]
1452 ; CHECK-NO-EXP10-LABEL: define float @test_pow_10_f32(
1453 ; CHECK-NO-EXP10-SAME: float [[X:%.*]]) {
1454 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call float @llvm.pow.f32(float 1.000000e+01, float [[X]])
1455 ; CHECK-NO-EXP10-NEXT: ret float [[RETVAL]]
1457 %retval = call float @llvm.pow.f32(float 10.0, float %x)
1461 define double @test_pow_10_f64(double %x) {
1462 ; CHECK-EXP10-LABEL: define double @test_pow_10_f64(
1463 ; CHECK-EXP10-SAME: double [[X:%.*]]) {
1464 ; CHECK-EXP10-NEXT: [[__EXP10:%.*]] = call double @llvm.exp10.f64(double [[X]])
1465 ; CHECK-EXP10-NEXT: ret double [[__EXP10]]
1467 ; CHECK-NO-EXP10-LABEL: define double @test_pow_10_f64(
1468 ; CHECK-NO-EXP10-SAME: double [[X:%.*]]) {
1469 ; CHECK-NO-EXP10-NEXT: [[RETVAL:%.*]] = call double @llvm.pow.f64(double 1.000000e+01, double [[X]])
1470 ; CHECK-NO-EXP10-NEXT: ret double [[RETVAL]]
1472 %retval = call double @llvm.pow.f64(double 10.0, double %x)
1476 define fp128 @test_pow_10_fp128(fp128 %x) {
1477 ; CHECK-LABEL: define fp128 @test_pow_10_fp128(
1478 ; CHECK-SAME: fp128 [[X:%.*]]) {
1479 ; CHECK-NEXT: [[RETVAL:%.*]] = call fp128 @llvm.pow.f128(fp128 0xL00000000000000004002400000000000, fp128 [[X]])
1480 ; CHECK-NEXT: ret fp128 [[RETVAL]]
1482 %ten = fpext double 10.0 to fp128
1483 %retval = call fp128 @llvm.pow.fp128(fp128 %ten, fp128 %x)
1487 define bfloat @test_pow_10_bf16(bfloat %x) {
1488 ; CHECK-LABEL: define bfloat @test_pow_10_bf16(
1489 ; CHECK-SAME: bfloat [[X:%.*]]) {
1490 ; CHECK-NEXT: [[RETVAL:%.*]] = call bfloat @llvm.pow.bf16(bfloat 0xR4120, bfloat [[X]])
1491 ; CHECK-NEXT: ret bfloat [[RETVAL]]
1493 %retval = call bfloat @llvm.pow.bf16(bfloat 10.0, bfloat %x)
1497 define <2 x half> @test_pow_10_v2f16(<2 x half> %x) {
1498 ; CHECK-LABEL: define <2 x half> @test_pow_10_v2f16(
1499 ; CHECK-SAME: <2 x half> [[X:%.*]]) {
1500 ; CHECK-NEXT: [[RETVAL:%.*]] = call <2 x half> @llvm.pow.v2f16(<2 x half> <half 0xH4900, half 0xH4900>, <2 x half> [[X]])
1501 ; CHECK-NEXT: ret <2 x half> [[RETVAL]]
1503 %retval = call <2 x half> @llvm.pow.v2f16(<2 x half> <half 10.0, half 10.0>, <2 x half> %x)
1504 ret <2 x half> %retval
1507 define <2 x float> @test_pow_10_v2f32(<2 x float> %x) {
1508 ; CHECK-LABEL: define <2 x float> @test_pow_10_v2f32(
1509 ; CHECK-SAME: <2 x float> [[X:%.*]]) {
1510 ; CHECK-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 1.000000e+01, float 1.000000e+01>, <2 x float> [[X]])
1511 ; CHECK-NEXT: ret <2 x float> [[RETVAL]]
1513 %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 10.0, float 10.0>, <2 x float> %x)
1514 ret <2 x float> %retval
1517 define <2 x double> @test_pow_10_v2f64(<2 x double> %x) {
1518 ; CHECK-LABEL: define <2 x double> @test_pow_10_v2f64(
1519 ; CHECK-SAME: <2 x double> [[X:%.*]]) {
1520 ; CHECK-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 1.000000e+01, double 1.000000e+01>, <2 x double> [[X]])
1521 ; CHECK-NEXT: ret <2 x double> [[RETVAL]]
1523 %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 10.0, double 10.0>, <2 x double> %x)
1524 ret <2 x double> %retval
1527 define <2 x bfloat> @test_pow_10_v2bf16(<2 x bfloat> %x) {
1528 ; CHECK-LABEL: define <2 x bfloat> @test_pow_10_v2bf16(
1529 ; CHECK-SAME: <2 x bfloat> [[X:%.*]]) {
1530 ; CHECK-NEXT: [[RETVAL:%.*]] = call <2 x bfloat> @llvm.pow.v2bf16(<2 x bfloat> <bfloat 0xR4120, bfloat 0xR4120>, <2 x bfloat> [[X]])
1531 ; CHECK-NEXT: ret <2 x bfloat> [[RETVAL]]
1533 %retval = call <2 x bfloat> @llvm.pow.v2bf16(<2 x bfloat> <bfloat 10.0, bfloat 10.0>, <2 x bfloat> %x)
1534 ret <2 x bfloat> %retval
1537 attributes #0 = { nounwind memory(none) }