1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2 ; RUN: opt -mtriple unknown -passes=instcombine -S < %s | FileCheck %s
3 target datalayout = "e"
6 ; Can't generate test checks due to PR42740.
8 define double @pow_sitofp_const_base_fast(i32 %x) {
9 ; CHECK-LABEL: define double @pow_sitofp_const_base_fast(
10 ; CHECK-SAME: i32 [[X:%.*]]) {
11 ; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float 7.000000e+00, i32 [[X]])
12 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
13 ; CHECK-NEXT: ret double [[RES]]
15 %subfp = sitofp i32 %x to float
16 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)
17 %res = fpext float %pow to double
21 define double @pow_uitofp_const_base_fast(i31 %x) {
22 ; CHECK-LABEL: define double @pow_uitofp_const_base_fast(
23 ; CHECK-SAME: i31 [[X:%.*]]) {
24 ; CHECK-NEXT: [[TMP1:%.*]] = zext i31 [[X]] to i32
25 ; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float 7.000000e+00, i32 [[TMP1]])
26 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
27 ; CHECK-NEXT: ret double [[RES]]
29 %subfp = uitofp i31 %x to float
30 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)
31 %res = fpext float %pow to double
35 define double @pow_sitofp_double_const_base_fast(i32 %x) {
36 ; CHECK-LABEL: define double @pow_sitofp_double_const_base_fast(
37 ; CHECK-SAME: i32 [[X:%.*]]) {
38 ; CHECK-NEXT: [[POW:%.*]] = tail call afn double @llvm.powi.f64.i32(double 7.000000e+00, i32 [[X]])
39 ; CHECK-NEXT: ret double [[POW]]
41 %subfp = sitofp i32 %x to double
42 %pow = tail call afn double @llvm.pow.f64(double 7.000000e+00, double %subfp)
46 define double @pow_uitofp_double_const_base_fast(i31 %x) {
47 ; CHECK-LABEL: define double @pow_uitofp_double_const_base_fast(
48 ; CHECK-SAME: i31 [[X:%.*]]) {
49 ; CHECK-NEXT: [[TMP1:%.*]] = zext i31 [[X]] to i32
50 ; CHECK-NEXT: [[POW:%.*]] = tail call afn double @llvm.powi.f64.i32(double 7.000000e+00, i32 [[TMP1]])
51 ; CHECK-NEXT: ret double [[POW]]
53 %subfp = uitofp i31 %x to double
54 %pow = tail call afn double @llvm.pow.f64(double 7.000000e+00, double %subfp)
58 define double @pow_sitofp_double_const_base_2_fast(i32 %x) {
59 ; CHECK-LABEL: define double @pow_sitofp_double_const_base_2_fast(
60 ; CHECK-SAME: i32 [[X:%.*]]) {
61 ; CHECK-NEXT: [[LDEXPF:%.*]] = tail call afn float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[X]])
62 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[LDEXPF]] to double
63 ; CHECK-NEXT: ret double [[RES]]
65 %subfp = sitofp i32 %x to float
66 %pow = tail call afn float @llvm.pow.f32(float 2.000000e+00, float %subfp)
67 %res = fpext float %pow to double
71 define double @pow_sitofp_double_const_base_power_of_2_fast(i32 %x) {
72 ; CHECK-LABEL: define double @pow_sitofp_double_const_base_power_of_2_fast(
73 ; CHECK-SAME: i32 [[X:%.*]]) {
74 ; CHECK-NEXT: [[SUBFP:%.*]] = sitofp i32 [[X]] to float
75 ; CHECK-NEXT: [[MUL:%.*]] = fmul afn float [[SUBFP]], 4.000000e+00
76 ; CHECK-NEXT: [[EXP2:%.*]] = tail call afn float @llvm.exp2.f32(float [[MUL]])
77 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double
78 ; CHECK-NEXT: ret double [[RES]]
80 %subfp = sitofp i32 %x to float
81 %pow = tail call afn float @llvm.pow.f32(float 16.000000e+00, float %subfp)
82 %res = fpext float %pow to double
86 define double @pow_uitofp_const_base_2_fast(i31 %x) {
87 ; CHECK-LABEL: define double @pow_uitofp_const_base_2_fast(
88 ; CHECK-SAME: i31 [[X:%.*]]) {
89 ; CHECK-NEXT: [[TMP1:%.*]] = zext i31 [[X]] to i32
90 ; CHECK-NEXT: [[LDEXPF:%.*]] = tail call afn float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
91 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[LDEXPF]] to double
92 ; CHECK-NEXT: ret double [[RES]]
94 %subfp = uitofp i31 %x to float
95 %pow = tail call afn float @llvm.pow.f32(float 2.000000e+00, float %subfp)
96 %res = fpext float %pow to double
100 define double @pow_uitofp_const_base_power_of_2_fast(i31 %x) {
101 ; CHECK-LABEL: define double @pow_uitofp_const_base_power_of_2_fast(
102 ; CHECK-SAME: i31 [[X:%.*]]) {
103 ; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i31 [[X]] to float
104 ; CHECK-NEXT: [[MUL:%.*]] = fmul afn float [[SUBFP]], 4.000000e+00
105 ; CHECK-NEXT: [[EXP2:%.*]] = tail call afn float @llvm.exp2.f32(float [[MUL]])
106 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double
107 ; CHECK-NEXT: ret double [[RES]]
109 %subfp = uitofp i31 %x to float
110 %pow = tail call afn float @llvm.pow.f32(float 16.000000e+00, float %subfp)
111 %res = fpext float %pow to double
115 define double @pow_sitofp_float_base_fast(float %base, i32 %x) {
116 ; CHECK-LABEL: define double @pow_sitofp_float_base_fast(
117 ; CHECK-SAME: float [[BASE:%.*]], i32 [[X:%.*]]) {
118 ; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float [[BASE]], i32 [[X]])
119 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
120 ; CHECK-NEXT: ret double [[RES]]
122 %subfp = sitofp i32 %x to float
123 %pow = tail call afn float @llvm.pow.f32(float %base, float %subfp)
124 %res = fpext float %pow to double
128 define double @pow_uitofp_float_base_fast(float %base, i31 %x) {
129 ; CHECK-LABEL: define double @pow_uitofp_float_base_fast(
130 ; CHECK-SAME: float [[BASE:%.*]], i31 [[X:%.*]]) {
131 ; CHECK-NEXT: [[TMP1:%.*]] = zext i31 [[X]] to i32
132 ; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float [[BASE]], i32 [[TMP1]])
133 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
134 ; CHECK-NEXT: ret double [[RES]]
136 %subfp = uitofp i31 %x to float
137 %pow = tail call afn float @llvm.pow.f32(float %base, float %subfp)
138 %res = fpext float %pow to double
142 define double @pow_sitofp_double_base_fast(double %base, i32 %x) {
143 ; CHECK-LABEL: define double @pow_sitofp_double_base_fast(
144 ; CHECK-SAME: double [[BASE:%.*]], i32 [[X:%.*]]) {
145 ; CHECK-NEXT: [[RES:%.*]] = tail call afn double @llvm.powi.f64.i32(double [[BASE]], i32 [[X]])
146 ; CHECK-NEXT: ret double [[RES]]
148 %subfp = sitofp i32 %x to double
149 %res = tail call afn double @llvm.pow.f64(double %base, double %subfp)
153 define double @pow_uitofp_double_base_fast(double %base, i31 %x) {
154 ; CHECK-LABEL: define double @pow_uitofp_double_base_fast(
155 ; CHECK-SAME: double [[BASE:%.*]], i31 [[X:%.*]]) {
156 ; CHECK-NEXT: [[TMP1:%.*]] = zext i31 [[X]] to i32
157 ; CHECK-NEXT: [[RES:%.*]] = tail call afn double @llvm.powi.f64.i32(double [[BASE]], i32 [[TMP1]])
158 ; CHECK-NEXT: ret double [[RES]]
160 %subfp = uitofp i31 %x to double
161 %res = tail call afn double @llvm.pow.f64(double %base, double %subfp)
165 define double @pow_sitofp_const_base_fast_i8(i8 %x) {
166 ; CHECK-LABEL: define double @pow_sitofp_const_base_fast_i8(
167 ; CHECK-SAME: i8 [[X:%.*]]) {
168 ; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
169 ; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float 7.000000e+00, i32 [[TMP1]])
170 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
171 ; CHECK-NEXT: ret double [[RES]]
173 %subfp = sitofp i8 %x to float
174 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)
175 %res = fpext float %pow to double
179 define double @pow_sitofp_const_base_fast_i16(i16 %x) {
180 ; CHECK-LABEL: define double @pow_sitofp_const_base_fast_i16(
181 ; CHECK-SAME: i16 [[X:%.*]]) {
182 ; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[X]] to i32
183 ; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float 7.000000e+00, i32 [[TMP1]])
184 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
185 ; CHECK-NEXT: ret double [[RES]]
187 %subfp = sitofp i16 %x to float
188 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)
189 %res = fpext float %pow to double
194 define double @pow_uitofp_const_base_fast_i8(i8 %x) {
195 ; CHECK-LABEL: define double @pow_uitofp_const_base_fast_i8(
196 ; CHECK-SAME: i8 [[X:%.*]]) {
197 ; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X]] to i32
198 ; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float 7.000000e+00, i32 [[TMP1]])
199 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
200 ; CHECK-NEXT: ret double [[RES]]
202 %subfp = uitofp i8 %x to float
203 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)
204 %res = fpext float %pow to double
208 define double @pow_uitofp_const_base_fast_i16(i16 %x) {
209 ; CHECK-LABEL: define double @pow_uitofp_const_base_fast_i16(
210 ; CHECK-SAME: i16 [[X:%.*]]) {
211 ; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[X]] to i32
212 ; CHECK-NEXT: [[POW:%.*]] = tail call afn float @llvm.powi.f32.i32(float 7.000000e+00, i32 [[TMP1]])
213 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
214 ; CHECK-NEXT: ret double [[RES]]
216 %subfp = uitofp i16 %x to float
217 %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)
218 %res = fpext float %pow to double
222 define double @powf_exp_const_int_fast(double %base) {
223 ; CHECK-LABEL: define double @powf_exp_const_int_fast(
224 ; CHECK-SAME: double [[BASE:%.*]]) {
225 ; CHECK-NEXT: [[RES:%.*]] = tail call fast double @llvm.powi.f64.i32(double [[BASE]], i32 40)
226 ; CHECK-NEXT: ret double [[RES]]
228 %res = tail call fast double @llvm.pow.f64(double %base, double 4.000000e+01)
232 define double @powf_exp_const2_int_fast(double %base) {
233 ; CHECK-LABEL: define double @powf_exp_const2_int_fast(
234 ; CHECK-SAME: double [[BASE:%.*]]) {
235 ; CHECK-NEXT: [[RES:%.*]] = tail call fast double @llvm.powi.f64.i32(double [[BASE]], i32 -40)
236 ; CHECK-NEXT: ret double [[RES]]
238 %res = tail call fast double @llvm.pow.f64(double %base, double -4.000000e+01)
244 define double @pow_uitofp_const_base_fast_i32(i32 %x) {
245 ; CHECK-LABEL: define double @pow_uitofp_const_base_fast_i32(
246 ; CHECK-SAME: i32 [[X:%.*]]) {
247 ; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float
248 ; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUBFP]], 0x4006757680000000
249 ; CHECK-NEXT: [[EXP2:%.*]] = tail call fast float @llvm.exp2.f32(float [[MUL]])
250 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double
251 ; CHECK-NEXT: ret double [[RES]]
253 %subfp = uitofp i32 %x to float
254 %pow = tail call fast float @llvm.pow.f32(float 7.000000e+00, float %subfp)
255 %res = fpext float %pow to double
259 define double @pow_uitofp_const_base_2_fast_i32(i32 %x) {
260 ; CHECK-LABEL: define double @pow_uitofp_const_base_2_fast_i32(
261 ; CHECK-SAME: i32 [[X:%.*]]) {
262 ; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float
263 ; CHECK-NEXT: [[EXP2:%.*]] = tail call fast float @llvm.exp2.f32(float [[SUBFP]])
264 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double
265 ; CHECK-NEXT: ret double [[RES]]
267 %subfp = uitofp i32 %x to float
268 %pow = tail call fast float @llvm.pow.f32(float 2.000000e+00, float %subfp)
269 %res = fpext float %pow to double
273 define double @pow_uitofp_const_base_power_of_2_fast_i32(i32 %x) {
274 ; CHECK-LABEL: define double @pow_uitofp_const_base_power_of_2_fast_i32(
275 ; CHECK-SAME: i32 [[X:%.*]]) {
276 ; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float
277 ; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUBFP]], 4.000000e+00
278 ; CHECK-NEXT: [[EXP2:%.*]] = tail call fast float @llvm.exp2.f32(float [[MUL]])
279 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double
280 ; CHECK-NEXT: ret double [[RES]]
282 %subfp = uitofp i32 %x to float
283 %pow = tail call fast float @llvm.pow.f32(float 16.000000e+00, float %subfp)
284 %res = fpext float %pow to double
288 define double @pow_uitofp_float_base_fast_i32(float %base, i32 %x) {
289 ; CHECK-LABEL: define double @pow_uitofp_float_base_fast_i32(
290 ; CHECK-SAME: float [[BASE:%.*]], i32 [[X:%.*]]) {
291 ; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float
292 ; CHECK-NEXT: [[POW:%.*]] = tail call fast float @llvm.pow.f32(float [[BASE]], float [[SUBFP]])
293 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
294 ; CHECK-NEXT: ret double [[RES]]
296 %subfp = uitofp i32 %x to float
297 %pow = tail call fast float @llvm.pow.f32(float %base, float %subfp)
298 %res = fpext float %pow to double
302 define double @pow_uitofp_double_base_fast_i32(double %base, i32 %x) {
303 ; CHECK-LABEL: define double @pow_uitofp_double_base_fast_i32(
304 ; CHECK-SAME: double [[BASE:%.*]], i32 [[X:%.*]]) {
305 ; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to double
306 ; CHECK-NEXT: [[RES:%.*]] = tail call fast double @llvm.pow.f64(double [[BASE]], double [[SUBFP]])
307 ; CHECK-NEXT: ret double [[RES]]
309 %subfp = uitofp i32 %x to double
310 %res = tail call fast double @llvm.pow.f64(double %base, double %subfp)
314 define double @pow_sitofp_const_base_fast_i64(i64 %x) {
315 ; CHECK-LABEL: define double @pow_sitofp_const_base_fast_i64(
316 ; CHECK-SAME: i64 [[X:%.*]]) {
317 ; CHECK-NEXT: [[SUBFP:%.*]] = sitofp i64 [[X]] to float
318 ; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUBFP]], 0x4006757680000000
319 ; CHECK-NEXT: [[EXP2:%.*]] = tail call fast float @llvm.exp2.f32(float [[MUL]])
320 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double
321 ; CHECK-NEXT: ret double [[RES]]
323 ; Do not change 0x400675{{.*}} to the exact constant, see PR42740
324 %subfp = sitofp i64 %x to float
325 %pow = tail call fast float @llvm.pow.f32(float 7.000000e+00, float %subfp)
326 %res = fpext float %pow to double
330 define double @pow_uitofp_const_base_fast_i64(i64 %x) {
331 ; CHECK-LABEL: define double @pow_uitofp_const_base_fast_i64(
332 ; CHECK-SAME: i64 [[X:%.*]]) {
333 ; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i64 [[X]] to float
334 ; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUBFP]], 0x4006757680000000
335 ; CHECK-NEXT: [[EXP2:%.*]] = tail call fast float @llvm.exp2.f32(float [[MUL]])
336 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double
337 ; CHECK-NEXT: ret double [[RES]]
339 %subfp = uitofp i64 %x to float
340 %pow = tail call fast float @llvm.pow.f32(float 7.000000e+00, float %subfp)
341 %res = fpext float %pow to double
345 define double @pow_sitofp_const_base_no_fast(i32 %x) {
346 ; CHECK-LABEL: define double @pow_sitofp_const_base_no_fast(
347 ; CHECK-SAME: i32 [[X:%.*]]) {
348 ; CHECK-NEXT: [[SUBFP:%.*]] = sitofp i32 [[X]] to float
349 ; CHECK-NEXT: [[POW:%.*]] = tail call float @llvm.pow.f32(float 7.000000e+00, float [[SUBFP]])
350 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
351 ; CHECK-NEXT: ret double [[RES]]
353 %subfp = sitofp i32 %x to float
354 %pow = tail call float @llvm.pow.f32(float 7.000000e+00, float %subfp)
355 %res = fpext float %pow to double
359 define double @pow_uitofp_const_base_no_fast(i32 %x) {
360 ; CHECK-LABEL: define double @pow_uitofp_const_base_no_fast(
361 ; CHECK-SAME: i32 [[X:%.*]]) {
362 ; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float
363 ; CHECK-NEXT: [[POW:%.*]] = tail call float @llvm.pow.f32(float 7.000000e+00, float [[SUBFP]])
364 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
365 ; CHECK-NEXT: ret double [[RES]]
367 %subfp = uitofp i32 %x to float
368 %pow = tail call float @llvm.pow.f32(float 7.000000e+00, float %subfp)
369 %res = fpext float %pow to double
373 define double @pow_sitofp_const_base_2_no_fast(i32 %x) {
374 ; CHECK-LABEL: define double @pow_sitofp_const_base_2_no_fast(
375 ; CHECK-SAME: i32 [[X:%.*]]) {
376 ; CHECK-NEXT: [[LDEXPF:%.*]] = tail call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[X]])
377 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[LDEXPF]] to double
378 ; CHECK-NEXT: ret double [[RES]]
380 %subfp = sitofp i32 %x to float
381 %pow = tail call float @llvm.pow.f32(float 2.000000e+00, float %subfp)
382 %res = fpext float %pow to double
386 define double @pow_sitofp_const_base_power_of_2_no_fast(i32 %x) {
387 ; CHECK-LABEL: define double @pow_sitofp_const_base_power_of_2_no_fast(
388 ; CHECK-SAME: i32 [[X:%.*]]) {
389 ; CHECK-NEXT: [[SUBFP:%.*]] = sitofp i32 [[X]] to float
390 ; CHECK-NEXT: [[MUL:%.*]] = fmul float [[SUBFP]], 4.000000e+00
391 ; CHECK-NEXT: [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[MUL]])
392 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double
393 ; CHECK-NEXT: ret double [[RES]]
395 %subfp = sitofp i32 %x to float
396 %pow = tail call float @llvm.pow.f32(float 16.000000e+00, float %subfp)
397 %res = fpext float %pow to double
401 define double @pow_uitofp_const_base_2_no_fast(i32 %x) {
402 ; CHECK-LABEL: define double @pow_uitofp_const_base_2_no_fast(
403 ; CHECK-SAME: i32 [[X:%.*]]) {
404 ; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float
405 ; CHECK-NEXT: [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[SUBFP]])
406 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double
407 ; CHECK-NEXT: ret double [[RES]]
409 %subfp = uitofp i32 %x to float
410 %pow = tail call float @llvm.pow.f32(float 2.000000e+00, float %subfp)
411 %res = fpext float %pow to double
415 define double @pow_uitofp_const_base_power_of_2_no_fast(i32 %x) {
416 ; CHECK-LABEL: define double @pow_uitofp_const_base_power_of_2_no_fast(
417 ; CHECK-SAME: i32 [[X:%.*]]) {
418 ; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float
419 ; CHECK-NEXT: [[MUL:%.*]] = fmul float [[SUBFP]], 4.000000e+00
420 ; CHECK-NEXT: [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[MUL]])
421 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double
422 ; CHECK-NEXT: ret double [[RES]]
424 %subfp = uitofp i32 %x to float
425 %pow = tail call float @llvm.pow.f32(float 16.000000e+00, float %subfp)
426 %res = fpext float %pow to double
430 define double @pow_sitofp_float_base_no_fast(float %base, i32 %x) {
431 ; CHECK-LABEL: define double @pow_sitofp_float_base_no_fast(
432 ; CHECK-SAME: float [[BASE:%.*]], i32 [[X:%.*]]) {
433 ; CHECK-NEXT: [[SUBFP:%.*]] = sitofp i32 [[X]] to float
434 ; CHECK-NEXT: [[POW:%.*]] = tail call float @llvm.pow.f32(float [[BASE]], float [[SUBFP]])
435 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
436 ; CHECK-NEXT: ret double [[RES]]
438 %subfp = sitofp i32 %x to float
439 %pow = tail call float @llvm.pow.f32(float %base, float %subfp)
440 %res = fpext float %pow to double
444 define double @pow_uitofp_float_base_no_fast(float %base, i32 %x) {
445 ; CHECK-LABEL: define double @pow_uitofp_float_base_no_fast(
446 ; CHECK-SAME: float [[BASE:%.*]], i32 [[X:%.*]]) {
447 ; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to float
448 ; CHECK-NEXT: [[POW:%.*]] = tail call float @llvm.pow.f32(float [[BASE]], float [[SUBFP]])
449 ; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
450 ; CHECK-NEXT: ret double [[RES]]
452 %subfp = uitofp i32 %x to float
453 %pow = tail call float @llvm.pow.f32(float %base, float %subfp)
454 %res = fpext float %pow to double
458 define double @pow_sitofp_double_base_no_fast(double %base, i32 %x) {
459 ; CHECK-LABEL: define double @pow_sitofp_double_base_no_fast(
460 ; CHECK-SAME: double [[BASE:%.*]], i32 [[X:%.*]]) {
461 ; CHECK-NEXT: [[SUBFP:%.*]] = sitofp i32 [[X]] to double
462 ; CHECK-NEXT: [[POW:%.*]] = tail call double @llvm.pow.f64(double [[BASE]], double [[SUBFP]])
463 ; CHECK-NEXT: ret double [[POW]]
465 %subfp = sitofp i32 %x to double
466 %pow = tail call double @llvm.pow.f64(double %base, double %subfp)
470 define double @pow_uitofp_double_base_no_fast(double %base, i32 %x) {
471 ; CHECK-LABEL: define double @pow_uitofp_double_base_no_fast(
472 ; CHECK-SAME: double [[BASE:%.*]], i32 [[X:%.*]]) {
473 ; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X]] to double
474 ; CHECK-NEXT: [[POW:%.*]] = tail call double @llvm.pow.f64(double [[BASE]], double [[SUBFP]])
475 ; CHECK-NEXT: ret double [[POW]]
477 %subfp = uitofp i32 %x to double
478 %pow = tail call double @llvm.pow.f64(double %base, double %subfp)
482 ; negative test - pow with no FMF is not the same as the loosely-specified powi
484 define double @powf_exp_const_int_no_fast(double %base) {
485 ; CHECK-LABEL: define double @powf_exp_const_int_no_fast(
486 ; CHECK-SAME: double [[BASE:%.*]]) {
487 ; CHECK-NEXT: [[RES:%.*]] = tail call double @llvm.pow.f64(double [[BASE]], double 4.000000e+01)
488 ; CHECK-NEXT: ret double [[RES]]
490 %res = tail call double @llvm.pow.f64(double %base, double 4.000000e+01)
494 define double @powf_exp_const_not_int_fast(double %base) {
495 ; CHECK-LABEL: define double @powf_exp_const_not_int_fast(
496 ; CHECK-SAME: double [[BASE:%.*]]) {
497 ; CHECK-NEXT: [[SQRT:%.*]] = call fast double @llvm.sqrt.f64(double [[BASE]])
498 ; CHECK-NEXT: [[TMP1:%.*]] = tail call fast double @llvm.powi.f64.i32(double [[BASE]], i32 37)
499 ; CHECK-NEXT: [[RES:%.*]] = fmul fast double [[TMP1]], [[SQRT]]
500 ; CHECK-NEXT: ret double [[RES]]
502 %res = tail call fast double @llvm.pow.f64(double %base, double 3.750000e+01)
506 define double @powf_exp_const_not_int_no_fast(double %base) {
507 ; CHECK-LABEL: define double @powf_exp_const_not_int_no_fast(
508 ; CHECK-SAME: double [[BASE:%.*]]) {
509 ; CHECK-NEXT: [[RES:%.*]] = tail call double @llvm.pow.f64(double [[BASE]], double 3.750000e+01)
510 ; CHECK-NEXT: ret double [[RES]]
512 %res = tail call double @llvm.pow.f64(double %base, double 3.750000e+01)
516 ; negative test - pow with no FMF is not the same as the loosely-specified powi
518 define double @powf_exp_const2_int_no_fast(double %base) {
519 ; CHECK-LABEL: define double @powf_exp_const2_int_no_fast(
520 ; CHECK-SAME: double [[BASE:%.*]]) {
521 ; CHECK-NEXT: [[RES:%.*]] = tail call double @llvm.pow.f64(double [[BASE]], double -4.000000e+01)
522 ; CHECK-NEXT: ret double [[RES]]
524 %res = tail call double @llvm.pow.f64(double %base, double -4.000000e+01)
528 ; TODO: This could be transformed the same as scalar if there is an ldexp intrinsic.
530 define <2 x float> @pow_sitofp_const_base_2_no_fast_vector(<2 x i8> %x) {
531 ; CHECK-LABEL: define <2 x float> @pow_sitofp_const_base_2_no_fast_vector(
532 ; CHECK-SAME: <2 x i8> [[X:%.*]]) {
533 ; CHECK-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X]] to <2 x i32>
534 ; CHECK-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> splat (float 1.000000e+00), <2 x i32> [[TMP1]])
535 ; CHECK-NEXT: ret <2 x float> [[EXP2]]
537 %s = sitofp <2 x i8> %x to <2 x float>
538 %r = call <2 x float> @llvm.pow.v2f32(<2 x float><float 2.0, float 2.0>, <2 x float> %s)
542 declare float @llvm.pow.f32(float, float)
543 declare double @llvm.pow.f64(double, double)
544 declare <2 x float> @llvm.pow.v2f32(<2 x float>, <2 x float>)