[ARM] MVE compare vector splat combine
[llvm-complete.git] / test / Transforms / InstCombine / pow_fp_int.ll
blob372a9e11c1ebff89b4f59a7df622b664991f64f9
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -instcombine -S < %s | FileCheck %s
4 ; PR42190
6 define double @pow_sitofp_const_base_fast(i32 %x) {
7 ; CHECK-LABEL: @pow_sitofp_const_base_fast(
8 ; CHECK-NEXT:    [[TMP1:%.*]] = call afn float @llvm.powi.f32(float 7.000000e+00, i32 [[X:%.*]])
9 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[TMP1]] to double
10 ; CHECK-NEXT:    ret double [[RES]]
12   %subfp = sitofp i32 %x to float
13   %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)
14   %res = fpext float %pow to double
15   ret double %res
18 define double @pow_uitofp_const_base_fast(i31 %x) {
19 ; CHECK-LABEL: @pow_uitofp_const_base_fast(
20 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i31 [[X:%.*]] to i32
21 ; CHECK-NEXT:    [[TMP2:%.*]] = call afn float @llvm.powi.f32(float 7.000000e+00, i32 [[TMP1]])
22 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[TMP2]] to double
23 ; CHECK-NEXT:    ret double [[RES]]
25   %subfp = uitofp i31 %x to float
26   %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)
27   %res = fpext float %pow to double
28   ret double %res
31 define double @pow_sitofp_double_const_base_fast(i32 %x) {
32 ; CHECK-LABEL: @pow_sitofp_double_const_base_fast(
33 ; CHECK-NEXT:    [[TMP1:%.*]] = call afn double @llvm.powi.f64(double 7.000000e+00, i32 [[X:%.*]])
34 ; CHECK-NEXT:    ret double [[TMP1]]
36   %subfp = sitofp i32 %x to double
37   %pow = tail call afn double @llvm.pow.f64(double 7.000000e+00, double %subfp)
38   ret double %pow
41 define double @pow_uitofp_double_const_base_fast(i31 %x) {
42 ; CHECK-LABEL: @pow_uitofp_double_const_base_fast(
43 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i31 [[X:%.*]] to i32
44 ; CHECK-NEXT:    [[TMP2:%.*]] = call afn double @llvm.powi.f64(double 7.000000e+00, i32 [[TMP1]])
45 ; CHECK-NEXT:    ret double [[TMP2]]
47   %subfp = uitofp i31 %x to double
48   %pow = tail call afn double @llvm.pow.f64(double 7.000000e+00, double %subfp)
49   ret double %pow
52 define double @pow_sitofp_double_const_base_power_of_2_fast(i32 %x) {
53 ; CHECK-LABEL: @pow_sitofp_double_const_base_power_of_2_fast(
54 ; CHECK-NEXT:    [[SUBFP:%.*]] = sitofp i32 [[X:%.*]] to float
55 ; CHECK-NEXT:    [[MUL:%.*]] = fmul afn float [[SUBFP]], 4.000000e+00
56 ; CHECK-NEXT:    [[EXP2:%.*]] = call afn float @llvm.exp2.f32(float [[MUL]])
57 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[EXP2]] to double
58 ; CHECK-NEXT:    ret double [[RES]]
60   %subfp = sitofp i32 %x to float
61   %pow = tail call afn float @llvm.pow.f32(float 16.000000e+00, float %subfp)
62   %res = fpext float %pow to double
63   ret double %res
66 define double @pow_uitofp_const_base_power_of_2_fast(i31 %x) {
67 ; CHECK-LABEL: @pow_uitofp_const_base_power_of_2_fast(
68 ; CHECK-NEXT:    [[SUBFP:%.*]] = uitofp i31 [[X:%.*]] to float
69 ; CHECK-NEXT:    [[MUL:%.*]] = fmul afn float [[SUBFP]], 4.000000e+00
70 ; CHECK-NEXT:    [[EXP2:%.*]] = call afn float @llvm.exp2.f32(float [[MUL]])
71 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[EXP2]] to double
72 ; CHECK-NEXT:    ret double [[RES]]
74   %subfp = uitofp i31 %x to float
75   %pow = tail call afn float @llvm.pow.f32(float 16.000000e+00, float %subfp)
76   %res = fpext float %pow to double
77   ret double %res
80 define double @pow_sitofp_float_base_fast(float %base, i32 %x) {
81 ; CHECK-LABEL: @pow_sitofp_float_base_fast(
82 ; CHECK-NEXT:    [[TMP1:%.*]] = call afn float @llvm.powi.f32(float [[BASE:%.*]], i32 [[X:%.*]])
83 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[TMP1]] to double
84 ; CHECK-NEXT:    ret double [[RES]]
86   %subfp = sitofp i32 %x to float
87   %pow = tail call afn float @llvm.pow.f32(float %base, float %subfp)
88   %res = fpext float %pow to double
89   ret double %res
92 define double @pow_uitofp_float_base_fast(float %base, i31 %x) {
93 ; CHECK-LABEL: @pow_uitofp_float_base_fast(
94 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i31 [[X:%.*]] to i32
95 ; CHECK-NEXT:    [[TMP2:%.*]] = call afn float @llvm.powi.f32(float [[BASE:%.*]], i32 [[TMP1]])
96 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[TMP2]] to double
97 ; CHECK-NEXT:    ret double [[RES]]
99   %subfp = uitofp i31 %x to float
100   %pow = tail call afn float @llvm.pow.f32(float %base, float %subfp)
101   %res = fpext float %pow to double
102   ret double %res
105 define double @pow_sitofp_double_base_fast(double %base, i32 %x) {
106 ; CHECK-LABEL: @pow_sitofp_double_base_fast(
107 ; CHECK-NEXT:    [[TMP1:%.*]] = call afn double @llvm.powi.f64(double [[BASE:%.*]], i32 [[X:%.*]])
108 ; CHECK-NEXT:    ret double [[TMP1]]
110   %subfp = sitofp i32 %x to double
111   %res = tail call afn double @llvm.pow.f64(double %base, double %subfp)
112   ret double %res
115 define double @pow_uitofp_double_base_fast(double %base, i31 %x) {
116 ; CHECK-LABEL: @pow_uitofp_double_base_fast(
117 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i31 [[X:%.*]] to i32
118 ; CHECK-NEXT:    [[TMP2:%.*]] = call afn double @llvm.powi.f64(double [[BASE:%.*]], i32 [[TMP1]])
119 ; CHECK-NEXT:    ret double [[TMP2]]
121   %subfp = uitofp i31 %x to double
122   %res = tail call afn double @llvm.pow.f64(double %base, double %subfp)
123   ret double %res
126 define double @pow_sitofp_const_base_fast_i8(i8 %x) {
127 ; CHECK-LABEL: @pow_sitofp_const_base_fast_i8(
128 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
129 ; CHECK-NEXT:    [[TMP2:%.*]] = call afn float @llvm.powi.f32(float 7.000000e+00, i32 [[TMP1]])
130 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[TMP2]] to double
131 ; CHECK-NEXT:    ret double [[RES]]
133   %subfp = sitofp i8 %x to float
134   %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)
135   %res = fpext float %pow to double
136   ret double %res
139 define double @pow_sitofp_const_base_fast_i16(i16 %x) {
140 ; CHECK-LABEL: @pow_sitofp_const_base_fast_i16(
141 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i16 [[X:%.*]] to i32
142 ; CHECK-NEXT:    [[TMP2:%.*]] = call afn float @llvm.powi.f32(float 7.000000e+00, i32 [[TMP1]])
143 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[TMP2]] to double
144 ; CHECK-NEXT:    ret double [[RES]]
146   %subfp = sitofp i16 %x to float
147   %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)
148   %res = fpext float %pow to double
149   ret double %res
153 define double @pow_uitofp_const_base_fast_i8(i8 %x) {
154 ; CHECK-LABEL: @pow_uitofp_const_base_fast_i8(
155 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
156 ; CHECK-NEXT:    [[TMP2:%.*]] = call afn float @llvm.powi.f32(float 7.000000e+00, i32 [[TMP1]])
157 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[TMP2]] to double
158 ; CHECK-NEXT:    ret double [[RES]]
160   %subfp = uitofp i8 %x to float
161   %pow = tail call afn float @llvm.pow.f32(float 7.000000e+00, float %subfp)
162   %res = fpext float %pow to double
163   ret double %res
166 define double @pow_uitofp_const_base_fast_i16(i16 %x) {
167 ; CHECK-LABEL: @pow_uitofp_const_base_fast_i16(
168 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32
169 ; CHECK-NEXT:    [[TMP2:%.*]] = call afn float @llvm.powi.f32(float 7.000000e+00, i32 [[TMP1]])
170 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[TMP2]] to double
171 ; CHECK-NEXT:    ret double [[RES]]
173   %subfp = uitofp i16 %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 @powf_exp_const_int_fast(double %base) {
180 ; CHECK-LABEL: @powf_exp_const_int_fast(
181 ; CHECK-NEXT:    [[TMP1:%.*]] = call fast double @llvm.powi.f64(double [[BASE:%.*]], i32 40)
182 ; CHECK-NEXT:    ret double [[TMP1]]
184   %res = tail call fast double @llvm.pow.f64(double %base, double 4.000000e+01)
185   ret double %res
188 define double @powf_exp_const2_int_fast(double %base) {
189 ; CHECK-LABEL: @powf_exp_const2_int_fast(
190 ; CHECK-NEXT:    [[TMP1:%.*]] = call fast double @llvm.powi.f64(double [[BASE:%.*]], i32 -40)
191 ; CHECK-NEXT:    ret double [[TMP1]]
193   %res = tail call fast double @llvm.pow.f64(double %base, double -4.000000e+01)
194   ret double %res
197 ; Negative tests
199 define double @pow_uitofp_const_base_fast_i32(i32 %x) {
200 ; CHECK-LABEL: @pow_uitofp_const_base_fast_i32(
201 ; CHECK-NEXT:    [[SUBFP:%.*]] = uitofp i32 [[X:%.*]] to float
202 ; CHECK-NEXT:    [[MUL:%.*]] = fmul fast float [[SUBFP]], 0x4006757680000000
203 ; CHECK-NEXT:    [[EXP2:%.*]] = call fast float @llvm.exp2.f32(float [[MUL]])
204 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[EXP2]] to double
205 ; CHECK-NEXT:    ret double [[RES]]
207   %subfp = uitofp i32 %x to float
208   %pow = tail call fast float @llvm.pow.f32(float 7.000000e+00, float %subfp)
209   %res = fpext float %pow to double
210   ret double %res
213 define double @pow_uitofp_const_base_power_of_2_fast_i32(i32 %x) {
214 ; CHECK-LABEL: @pow_uitofp_const_base_power_of_2_fast_i32(
215 ; CHECK-NEXT:    [[SUBFP:%.*]] = uitofp i32 [[X:%.*]] to float
216 ; CHECK-NEXT:    [[MUL:%.*]] = fmul fast float [[SUBFP]], 4.000000e+00
217 ; CHECK-NEXT:    [[EXP2:%.*]] = call fast float @llvm.exp2.f32(float [[MUL]])
218 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[EXP2]] to double
219 ; CHECK-NEXT:    ret double [[RES]]
221   %subfp = uitofp i32 %x to float
222   %pow = tail call fast float @llvm.pow.f32(float 16.000000e+00, float %subfp)
223   %res = fpext float %pow to double
224   ret double %res
227 define double @pow_uitofp_float_base_fast_i32(float %base, i32 %x) {
228 ; CHECK-LABEL: @pow_uitofp_float_base_fast_i32(
229 ; CHECK-NEXT:    [[SUBFP:%.*]] = uitofp i32 [[X:%.*]] to float
230 ; CHECK-NEXT:    [[POW:%.*]] = tail call fast float @llvm.pow.f32(float [[BASE:%.*]], float [[SUBFP]])
231 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[POW]] to double
232 ; CHECK-NEXT:    ret double [[RES]]
234   %subfp = uitofp i32 %x to float
235   %pow = tail call fast float @llvm.pow.f32(float %base, float %subfp)
236   %res = fpext float %pow to double
237   ret double %res
240 define double @pow_uitofp_double_base_fast_i32(double %base, i32 %x) {
241 ; CHECK-LABEL: @pow_uitofp_double_base_fast_i32(
242 ; CHECK-NEXT:    [[SUBFP:%.*]] = uitofp i32 [[X:%.*]] to double
243 ; CHECK-NEXT:    [[RES:%.*]] = tail call fast double @llvm.pow.f64(double [[BASE:%.*]], double [[SUBFP]])
244 ; CHECK-NEXT:    ret double [[RES]]
246   %subfp = uitofp i32 %x to double
247   %res = tail call fast double @llvm.pow.f64(double %base, double %subfp)
248   ret double %res
251 define double @pow_sitofp_const_base_fast_i64(i64 %x) {
252 ; CHECK-LABEL: @pow_sitofp_const_base_fast_i64(
253 ; CHECK-NEXT:    [[SUBFP:%.*]] = sitofp i64 [[X:%.*]] to float
254 ; CHECK-NEXT:    [[MUL:%.*]] = fmul fast float [[SUBFP]], 0x4006757680000000
255 ; CHECK-NEXT:    [[EXP2:%.*]] = call fast float @llvm.exp2.f32(float [[MUL]])
256 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[EXP2]] to double
257 ; CHECK-NEXT:    ret double [[RES]]
259   %subfp = sitofp i64 %x to float
260   %pow = tail call fast float @llvm.pow.f32(float 7.000000e+00, float %subfp)
261   %res = fpext float %pow to double
262   ret double %res
265 define double @pow_uitofp_const_base_fast_i64(i64 %x) {
266 ; CHECK-LABEL: @pow_uitofp_const_base_fast_i64(
267 ; CHECK-NEXT:    [[SUBFP:%.*]] = uitofp i64 [[X:%.*]] to float
268 ; CHECK-NEXT:    [[MUL:%.*]] = fmul fast float [[SUBFP]], 0x4006757680000000
269 ; CHECK-NEXT:    [[EXP2:%.*]] = call fast float @llvm.exp2.f32(float [[MUL]])
270 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[EXP2]] to double
271 ; CHECK-NEXT:    ret double [[RES]]
273   %subfp = uitofp i64 %x to float
274   %pow = tail call fast float @llvm.pow.f32(float 7.000000e+00, float %subfp)
275   %res = fpext float %pow to double
276   ret double %res
279 define double @pow_sitofp_const_base_no_fast(i32 %x) {
280 ; CHECK-LABEL: @pow_sitofp_const_base_no_fast(
281 ; CHECK-NEXT:    [[SUBFP:%.*]] = sitofp i32 [[X:%.*]] to float
282 ; CHECK-NEXT:    [[POW:%.*]] = tail call float @llvm.pow.f32(float 7.000000e+00, float [[SUBFP]])
283 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[POW]] to double
284 ; CHECK-NEXT:    ret double [[RES]]
286   %subfp = sitofp i32 %x to float
287   %pow = tail call float @llvm.pow.f32(float 7.000000e+00, float %subfp)
288   %res = fpext float %pow to double
289   ret double %res
292 define double @pow_uitofp_const_base_no_fast(i32 %x) {
293 ; CHECK-LABEL: @pow_uitofp_const_base_no_fast(
294 ; CHECK-NEXT:    [[SUBFP:%.*]] = uitofp i32 [[X:%.*]] to float
295 ; CHECK-NEXT:    [[POW:%.*]] = tail call float @llvm.pow.f32(float 7.000000e+00, float [[SUBFP]])
296 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[POW]] to double
297 ; CHECK-NEXT:    ret double [[RES]]
299   %subfp = uitofp i32 %x to float
300   %pow = tail call float @llvm.pow.f32(float 7.000000e+00, float %subfp)
301   %res = fpext float %pow to double
302   ret double %res
305 define double @pow_sitofp_const_base_power_of_2_no_fast(i32 %x) {
306 ; CHECK-LABEL: @pow_sitofp_const_base_power_of_2_no_fast(
307 ; CHECK-NEXT:    [[SUBFP:%.*]] = sitofp i32 [[X:%.*]] to float
308 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUBFP]], 4.000000e+00
309 ; CHECK-NEXT:    [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[MUL]])
310 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[EXP2]] to double
311 ; CHECK-NEXT:    ret double [[RES]]
313   %subfp = sitofp i32 %x to float
314   %pow = tail call float @llvm.pow.f32(float 16.000000e+00, float %subfp)
315   %res = fpext float %pow to double
316   ret double %res
319 define double @pow_uitofp_const_base_power_of_2_no_fast(i32 %x) {
320 ; CHECK-LABEL: @pow_uitofp_const_base_power_of_2_no_fast(
321 ; CHECK-NEXT:    [[SUBFP:%.*]] = uitofp i32 [[X:%.*]] to float
322 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[SUBFP]], 4.000000e+00
323 ; CHECK-NEXT:    [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[MUL]])
324 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[EXP2]] to double
325 ; CHECK-NEXT:    ret double [[RES]]
327   %subfp = uitofp i32 %x to float
328   %pow = tail call float @llvm.pow.f32(float 16.000000e+00, float %subfp)
329   %res = fpext float %pow to double
330   ret double %res
333 define double @pow_sitofp_float_base_no_fast(float %base, i32 %x) {
334 ; CHECK-LABEL: @pow_sitofp_float_base_no_fast(
335 ; CHECK-NEXT:    [[SUBFP:%.*]] = sitofp i32 [[X:%.*]] to float
336 ; CHECK-NEXT:    [[POW:%.*]] = tail call float @llvm.pow.f32(float [[BASE:%.*]], float [[SUBFP]])
337 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[POW]] to double
338 ; CHECK-NEXT:    ret double [[RES]]
340   %subfp = sitofp i32 %x to float
341   %pow = tail call float @llvm.pow.f32(float %base, float %subfp)
342   %res = fpext float %pow to double
343   ret double %res
346 define double @pow_uitofp_float_base_no_fast(float %base, i32 %x) {
347 ; CHECK-LABEL: @pow_uitofp_float_base_no_fast(
348 ; CHECK-NEXT:    [[SUBFP:%.*]] = uitofp i32 [[X:%.*]] to float
349 ; CHECK-NEXT:    [[POW:%.*]] = tail call float @llvm.pow.f32(float [[BASE:%.*]], float [[SUBFP]])
350 ; CHECK-NEXT:    [[RES:%.*]] = fpext float [[POW]] to double
351 ; CHECK-NEXT:    ret double [[RES]]
353   %subfp = uitofp i32 %x to float
354   %pow = tail call float @llvm.pow.f32(float %base, float %subfp)
355   %res = fpext float %pow to double
356   ret double %res
359 define double @pow_sitofp_double_base_no_fast(double %base, i32 %x) {
360 ; CHECK-LABEL: @pow_sitofp_double_base_no_fast(
361 ; CHECK-NEXT:    [[SUBFP:%.*]] = sitofp i32 [[X:%.*]] to double
362 ; CHECK-NEXT:    [[POW:%.*]] = tail call double @llvm.pow.f64(double [[BASE:%.*]], double [[SUBFP]])
363 ; CHECK-NEXT:    ret double [[POW]]
365   %subfp = sitofp i32 %x to double
366   %pow = tail call double @llvm.pow.f64(double %base, double %subfp)
367   ret double %pow
370 define double @pow_uitofp_double_base_no_fast(double %base, i32 %x) {
371 ; CHECK-LABEL: @pow_uitofp_double_base_no_fast(
372 ; CHECK-NEXT:    [[SUBFP:%.*]] = uitofp i32 [[X:%.*]] to double
373 ; CHECK-NEXT:    [[POW:%.*]] = tail call double @llvm.pow.f64(double [[BASE:%.*]], double [[SUBFP]])
374 ; CHECK-NEXT:    ret double [[POW]]
376   %subfp = uitofp i32 %x to double
377   %pow = tail call double @llvm.pow.f64(double %base, double %subfp)
378   ret double %pow
381 define double @powf_exp_const_int_no_fast(double %base) {
382 ; CHECK-LABEL: @powf_exp_const_int_no_fast(
383 ; CHECK-NEXT:    [[RES:%.*]] = tail call double @llvm.pow.f64(double [[BASE:%.*]], double 4.000000e+01)
384 ; CHECK-NEXT:    ret double [[RES]]
386   %res = tail call double @llvm.pow.f64(double %base, double 4.000000e+01)
387   ret double %res
390 define double @powf_exp_const_not_int_fast(double %base) {
391 ; CHECK-LABEL: @powf_exp_const_not_int_fast(
392 ; CHECK-NEXT:    [[RES:%.*]] = tail call fast double @llvm.pow.f64(double [[BASE:%.*]], double 3.750000e+01)
393 ; CHECK-NEXT:    ret double [[RES]]
395   %res = tail call fast double @llvm.pow.f64(double %base, double 3.750000e+01)
396   ret double %res
399 define double @powf_exp_const_not_int_no_fast(double %base) {
400 ; CHECK-LABEL: @powf_exp_const_not_int_no_fast(
401 ; CHECK-NEXT:    [[RES:%.*]] = tail call double @llvm.pow.f64(double [[BASE:%.*]], double 3.750000e+01)
402 ; CHECK-NEXT:    ret double [[RES]]
404   %res = tail call double @llvm.pow.f64(double %base, double 3.750000e+01)
405   ret double %res
408 define double @powf_exp_const2_int_no_fast(double %base) {
409 ; CHECK-LABEL: @powf_exp_const2_int_no_fast(
410 ; CHECK-NEXT:    [[RES:%.*]] = tail call double @llvm.pow.f64(double [[BASE:%.*]], double -4.000000e+01)
411 ; CHECK-NEXT:    ret double [[RES]]
413   %res = tail call double @llvm.pow.f64(double %base, double -4.000000e+01)
414   ret double %res
417 declare float @llvm.pow.f32(float, float)
418 declare double @llvm.pow.f64(double, double)