[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / InstCombine / pow_fp_int.ll
blob4a75a84d7b66de9d283425bd5b49e82ff1675470
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"
5 ; PR42190
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
18   ret double %res
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
32   ret double %res
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)
43   ret double %pow
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)
55   ret double %pow
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
68   ret double %res
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
83   ret double %res
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
97   ret double %res
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
112   ret double %res
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
125   ret double %res
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
139   ret double %res
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)
150   ret double %res
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)
162   ret double %res
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
176   ret double %res
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
190   ret double %res
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
205   ret double %res
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
219   ret double %res
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)
229   ret double %res
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)
239   ret double %res
242 ; Negative tests
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
256   ret double %res
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
270   ret double %res
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
285   ret double %res
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
299   ret double %res
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)
311   ret double %res
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
327   ret double %res
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
342   ret double %res
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
356   ret double %res
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
370   ret double %res
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
383   ret double %res
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
398   ret double %res
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
412   ret double %res
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
427   ret double %res
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
441   ret double %res
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
455   ret double %res
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)
467   ret double %pow
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)
479   ret double %pow
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)
491   ret double %res
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)
503   ret double %res
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)
513   ret double %res
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)
525   ret double %res
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)
539   ret <2 x float> %r
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>)