[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / InstCombine / pow-to-ldexp.ll
blob0c4418a3094f96fa6026761eec4bfc31fadc4c7a
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2 ; RUN: opt -S -passes=instcombine %s | FileCheck -check-prefixes=CHECK,LDEXP,LDEXP-EXP2 %s
3 ; RUN: opt -S -passes=instcombine -disable-builtin=exp2f -disable-builtin=exp2 -disable-builtin=exp2l %s | FileCheck -check-prefixes=CHECK,LDEXP,LDEXP-NOEXP2 %s
4 ; RUN: opt -S -passes=instcombine -disable-builtin=ldexpf -disable-builtin=ldexp -disable-builtin=ldexpl %s | FileCheck -check-prefixes=CHECK,NOLDEXP %s
7 define float @pow_sitofp_f32_const_base_2(i32 %x) {
8 ; CHECK-LABEL: define float @pow_sitofp_f32_const_base_2(
9 ; CHECK-SAME: i32 [[X:%.*]]) {
10 ; CHECK-NEXT:    [[EXP2:%.*]] = tail call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[X]])
11 ; CHECK-NEXT:    ret float [[EXP2]]
13   %itofp = sitofp i32 %x to float
14   %pow = tail call float @llvm.pow.f32(float 2.000000e+00, float %itofp)
15   ret float %pow
18 define float @pow_sitofp_f32_const_base_2__flags(i32 %x) {
19 ; CHECK-LABEL: define float @pow_sitofp_f32_const_base_2__flags(
20 ; CHECK-SAME: i32 [[X:%.*]]) {
21 ; CHECK-NEXT:    [[EXP2:%.*]] = tail call nnan nsz float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[X]])
22 ; CHECK-NEXT:    ret float [[EXP2]]
24   %itofp = sitofp i32 %x to float
25   %pow = tail call nsz nnan float @llvm.pow.f32(float 2.000000e+00, float %itofp)
26   ret float %pow
29 define float @pow_uitofp_f32_const_base_2(i32 %x) {
30 ; LDEXP-EXP2-LABEL: define float @pow_uitofp_f32_const_base_2(
31 ; LDEXP-EXP2-SAME: i32 [[X:%.*]]) {
32 ; LDEXP-EXP2-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to float
33 ; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[ITOFP]])
34 ; LDEXP-EXP2-NEXT:    ret float [[EXP2]]
36 ; LDEXP-NOEXP2-LABEL: define float @pow_uitofp_f32_const_base_2(
37 ; LDEXP-NOEXP2-SAME: i32 [[X:%.*]]) {
38 ; LDEXP-NOEXP2-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to float
39 ; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call float @llvm.pow.f32(float 2.000000e+00, float [[ITOFP]])
40 ; LDEXP-NOEXP2-NEXT:    ret float [[POW]]
42 ; NOLDEXP-LABEL: define float @pow_uitofp_f32_const_base_2(
43 ; NOLDEXP-SAME: i32 [[X:%.*]]) {
44 ; NOLDEXP-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to float
45 ; NOLDEXP-NEXT:    [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[ITOFP]])
46 ; NOLDEXP-NEXT:    ret float [[EXP2]]
48   %itofp = uitofp i32 %x to float
49   %pow = tail call float @llvm.pow.f32(float 2.000000e+00, float %itofp)
50   ret float %pow
53 define float @pow_sitofp_f32_const_base_4(i32 %x) {
54 ; LDEXP-EXP2-LABEL: define float @pow_sitofp_f32_const_base_4(
55 ; LDEXP-EXP2-SAME: i32 [[X:%.*]]) {
56 ; LDEXP-EXP2-NEXT:    [[ITOFP:%.*]] = sitofp i32 [[X]] to float
57 ; LDEXP-EXP2-NEXT:    [[MUL:%.*]] = fmul float [[ITOFP]], 2.000000e+00
58 ; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[MUL]])
59 ; LDEXP-EXP2-NEXT:    ret float [[EXP2]]
61 ; LDEXP-NOEXP2-LABEL: define float @pow_sitofp_f32_const_base_4(
62 ; LDEXP-NOEXP2-SAME: i32 [[X:%.*]]) {
63 ; LDEXP-NOEXP2-NEXT:    [[ITOFP:%.*]] = sitofp i32 [[X]] to float
64 ; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call float @llvm.pow.f32(float 4.000000e+00, float [[ITOFP]])
65 ; LDEXP-NOEXP2-NEXT:    ret float [[POW]]
67 ; NOLDEXP-LABEL: define float @pow_sitofp_f32_const_base_4(
68 ; NOLDEXP-SAME: i32 [[X:%.*]]) {
69 ; NOLDEXP-NEXT:    [[ITOFP:%.*]] = sitofp i32 [[X]] to float
70 ; NOLDEXP-NEXT:    [[MUL:%.*]] = fmul float [[ITOFP]], 2.000000e+00
71 ; NOLDEXP-NEXT:    [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[MUL]])
72 ; NOLDEXP-NEXT:    ret float [[EXP2]]
74   %itofp = sitofp i32 %x to float
75   %pow = tail call float @llvm.pow.f32(float 4.000000e+00, float %itofp)
76   ret float %pow
79 define float @pow_sitofp_f32_const_base_16(i32 %x) {
80 ; LDEXP-EXP2-LABEL: define float @pow_sitofp_f32_const_base_16(
81 ; LDEXP-EXP2-SAME: i32 [[X:%.*]]) {
82 ; LDEXP-EXP2-NEXT:    [[ITOFP:%.*]] = sitofp i32 [[X]] to float
83 ; LDEXP-EXP2-NEXT:    [[MUL:%.*]] = fmul float [[ITOFP]], 4.000000e+00
84 ; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[MUL]])
85 ; LDEXP-EXP2-NEXT:    ret float [[EXP2]]
87 ; LDEXP-NOEXP2-LABEL: define float @pow_sitofp_f32_const_base_16(
88 ; LDEXP-NOEXP2-SAME: i32 [[X:%.*]]) {
89 ; LDEXP-NOEXP2-NEXT:    [[ITOFP:%.*]] = sitofp i32 [[X]] to float
90 ; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call float @llvm.pow.f32(float 1.600000e+01, float [[ITOFP]])
91 ; LDEXP-NOEXP2-NEXT:    ret float [[POW]]
93 ; NOLDEXP-LABEL: define float @pow_sitofp_f32_const_base_16(
94 ; NOLDEXP-SAME: i32 [[X:%.*]]) {
95 ; NOLDEXP-NEXT:    [[ITOFP:%.*]] = sitofp i32 [[X]] to float
96 ; NOLDEXP-NEXT:    [[MUL:%.*]] = fmul float [[ITOFP]], 4.000000e+00
97 ; NOLDEXP-NEXT:    [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[MUL]])
98 ; NOLDEXP-NEXT:    ret float [[EXP2]]
100   %itofp = sitofp i32 %x to float
101   %pow = tail call float @llvm.pow.f32(float 16.000000e+00, float %itofp)
102   ret float %pow
105 define double @pow_sitofp_f64_const_base_2(i32 %x) {
106 ; CHECK-LABEL: define double @pow_sitofp_f64_const_base_2(
107 ; CHECK-SAME: i32 [[X:%.*]]) {
108 ; CHECK-NEXT:    [[EXP2:%.*]] = tail call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[X]])
109 ; CHECK-NEXT:    ret double [[EXP2]]
111   %itofp = sitofp i32 %x to double
112   %pow = tail call double @llvm.pow.f64(double 2.000000e+00, double %itofp)
113   ret double %pow
116 define half @pow_sitofp_f16_const_base_2(i32 %x) {
117 ; CHECK-LABEL: define half @pow_sitofp_f16_const_base_2(
118 ; CHECK-SAME: i32 [[X:%.*]]) {
119 ; CHECK-NEXT:    [[POW:%.*]] = tail call half @llvm.ldexp.f16.i32(half 0xH3C00, i32 [[X]])
120 ; CHECK-NEXT:    ret half [[POW]]
122   %itofp = sitofp i32 %x to half
123   %pow = tail call half @llvm.pow.f16(half 2.000000e+00, half %itofp)
124   ret half %pow
127 define <2 x float> @pow_sitofp_v2f32_const_base_2(<2 x i32> %x) {
128 ; CHECK-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2(
129 ; CHECK-SAME: <2 x i32> [[X:%.*]]) {
130 ; CHECK-NEXT:    [[EXP2:%.*]] = tail call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> splat (float 1.000000e+00), <2 x i32> [[X]])
131 ; CHECK-NEXT:    ret <2 x float> [[EXP2]]
133   %itofp = sitofp <2 x i32> %x to <2 x float>
134   %pow = tail call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 2.000000e+00>, <2 x float> %itofp)
135   ret <2 x float> %pow
138 define <2 x float> @pow_sitofp_v2f32_const_base_8(<2 x i32> %x) {
139 ; LDEXP-EXP2-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_8(
140 ; LDEXP-EXP2-SAME: <2 x i32> [[X:%.*]]) {
141 ; LDEXP-EXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x float>
142 ; LDEXP-EXP2-NEXT:    [[MUL:%.*]] = fmul <2 x float> [[ITOFP]], splat (float 3.000000e+00)
143 ; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call <2 x float> @llvm.exp2.v2f32(<2 x float> [[MUL]])
144 ; LDEXP-EXP2-NEXT:    ret <2 x float> [[EXP2]]
146 ; LDEXP-NOEXP2-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_8(
147 ; LDEXP-NOEXP2-SAME: <2 x i32> [[X:%.*]]) {
148 ; LDEXP-NOEXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x float>
149 ; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call <2 x float> @llvm.pow.v2f32(<2 x float> splat (float 8.000000e+00), <2 x float> [[ITOFP]])
150 ; LDEXP-NOEXP2-NEXT:    ret <2 x float> [[POW]]
152 ; NOLDEXP-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_8(
153 ; NOLDEXP-SAME: <2 x i32> [[X:%.*]]) {
154 ; NOLDEXP-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x float>
155 ; NOLDEXP-NEXT:    [[MUL:%.*]] = fmul <2 x float> [[ITOFP]], splat (float 3.000000e+00)
156 ; NOLDEXP-NEXT:    [[EXP2:%.*]] = tail call <2 x float> @llvm.exp2.v2f32(<2 x float> [[MUL]])
157 ; NOLDEXP-NEXT:    ret <2 x float> [[EXP2]]
159   %itofp = sitofp <2 x i32> %x to <2 x float>
160   %pow = tail call <2 x float> @llvm.pow.v2f32(<2 x float> <float 8.000000e+00, float 8.000000e+00>, <2 x float> %itofp)
161   ret <2 x float> %pow
164 define <2 x float> @pow_sitofp_v2f32_const_base_mixed_2(<2 x i32> %x) {
165 ; CHECK-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_mixed_2(
166 ; CHECK-SAME: <2 x i32> [[X:%.*]]) {
167 ; CHECK-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x float>
168 ; CHECK-NEXT:    [[POW:%.*]] = tail call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 4.000000e+00>, <2 x float> [[ITOFP]])
169 ; CHECK-NEXT:    ret <2 x float> [[POW]]
171   %itofp = sitofp <2 x i32> %x to <2 x float>
172   %pow = tail call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 4.000000e+00>, <2 x float> %itofp)
173   ret <2 x float> %pow
176 define <2 x float> @pow_sitofp_v2f32_const_base_2__flags(<2 x i32> %x) {
177 ; CHECK-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2__flags(
178 ; CHECK-SAME: <2 x i32> [[X:%.*]]) {
179 ; CHECK-NEXT:    [[EXP2:%.*]] = tail call nsz afn <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> splat (float 1.000000e+00), <2 x i32> [[X]])
180 ; CHECK-NEXT:    ret <2 x float> [[EXP2]]
182   %itofp = sitofp <2 x i32> %x to <2 x float>
183   %pow = tail call nsz afn <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 2.000000e+00>, <2 x float> %itofp)
184   ret <2 x float> %pow
187 define <vscale x 4 x float> @pow_sitofp_nxv4f32_const_base_2(<vscale x 4 x i32> %x) {
188 ; CHECK-LABEL: define <vscale x 4 x float> @pow_sitofp_nxv4f32_const_base_2(
189 ; CHECK-SAME: <vscale x 4 x i32> [[X:%.*]]) {
190 ; CHECK-NEXT:    [[EXP2:%.*]] = tail call <vscale x 4 x float> @llvm.ldexp.nxv4f32.nxv4i32(<vscale x 4 x float> shufflevector (<vscale x 4 x float> insertelement (<vscale x 4 x float> poison, float 1.000000e+00, i64 0), <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer), <vscale x 4 x i32> [[X]])
191 ; CHECK-NEXT:    ret <vscale x 4 x float> [[EXP2]]
193   %itofp = sitofp <vscale x 4 x i32> %x to <vscale x 4 x float>
194   %pow = tail call <vscale x 4 x float> @llvm.pow.nxv4f32(<vscale x 4 x float> splat (float 2.0), <vscale x 4 x float> %itofp)
195   ret <vscale x 4 x float> %pow
198 define <2 x half> @pow_sitofp_v2f16_const_base_2(<2 x i32> %x) {
199 ; CHECK-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_2(
200 ; CHECK-SAME: <2 x i32> [[X:%.*]]) {
201 ; CHECK-NEXT:    [[EXP2:%.*]] = tail call <2 x half> @llvm.ldexp.v2f16.v2i32(<2 x half> splat (half 0xH3C00), <2 x i32> [[X]])
202 ; CHECK-NEXT:    ret <2 x half> [[EXP2]]
204   %itofp = sitofp <2 x i32> %x to <2 x half>
205   %pow = tail call <2 x half> @llvm.pow.v2f16(<2 x half> <half 2.000000e+00, half 2.000000e+00>, <2 x half> %itofp)
206   ret <2 x half> %pow
209 define <2 x double> @pow_sitofp_v2f64_const_base_2(<2 x i32> %x) {
210 ; CHECK-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_2(
211 ; CHECK-SAME: <2 x i32> [[X:%.*]]) {
212 ; CHECK-NEXT:    [[EXP2:%.*]] = tail call <2 x double> @llvm.ldexp.v2f64.v2i32(<2 x double> splat (double 1.000000e+00), <2 x i32> [[X]])
213 ; CHECK-NEXT:    ret <2 x double> [[EXP2]]
215   %itofp = sitofp <2 x i32> %x to <2 x double>
216   %pow = tail call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.000000e+00, double 2.000000e+00>, <2 x double> %itofp)
217   ret <2 x double> %pow
220 define <2 x half> @pow_sitofp_v2f16_const_base_8(<2 x i32> %x) {
221 ; EXP2-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_8(
222 ; EXP2-SAME: <2 x i32> [[X:%.*]]) {
223 ; EXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x half>
224 ; EXP2-NEXT:    [[MUL:%.*]] = fmul <2 x half> [[ITOFP]], <half 0xH4200, half 0xH4200>
225 ; EXP2-NEXT:    [[EXP2:%.*]] = tail call <2 x half> @llvm.exp2.v2f16(<2 x half> [[MUL]])
226 ; EXP2-NEXT:    ret <2 x half> [[EXP2]]
228 ; LDEXP-EXP2-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_8(
229 ; LDEXP-EXP2-SAME: <2 x i32> [[X:%.*]]) {
230 ; LDEXP-EXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x half>
231 ; LDEXP-EXP2-NEXT:    [[MUL:%.*]] = fmul <2 x half> [[ITOFP]], splat (half 0xH4200)
232 ; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call <2 x half> @llvm.exp2.v2f16(<2 x half> [[MUL]])
233 ; LDEXP-EXP2-NEXT:    ret <2 x half> [[EXP2]]
235 ; LDEXP-NOEXP2-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_8(
236 ; LDEXP-NOEXP2-SAME: <2 x i32> [[X:%.*]]) {
237 ; LDEXP-NOEXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x half>
238 ; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call <2 x half> @llvm.pow.v2f16(<2 x half> splat (half 0xH4800), <2 x half> [[ITOFP]])
239 ; LDEXP-NOEXP2-NEXT:    ret <2 x half> [[POW]]
241 ; NOLDEXP-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_8(
242 ; NOLDEXP-SAME: <2 x i32> [[X:%.*]]) {
243 ; NOLDEXP-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x half>
244 ; NOLDEXP-NEXT:    [[MUL:%.*]] = fmul <2 x half> [[ITOFP]], splat (half 0xH4200)
245 ; NOLDEXP-NEXT:    [[EXP2:%.*]] = tail call <2 x half> @llvm.exp2.v2f16(<2 x half> [[MUL]])
246 ; NOLDEXP-NEXT:    ret <2 x half> [[EXP2]]
248   %itofp = sitofp <2 x i32> %x to <2 x half>
249   %pow = tail call <2 x half> @llvm.pow.v2f16(<2 x half> <half 8.000000e+00, half 8.000000e+00>, <2 x half> %itofp)
250   ret <2 x half> %pow
253 define <2 x double> @pow_sitofp_v2f64_const_base_8(<2 x i32> %x) {
254 ; EXP2-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_8(
255 ; EXP2-SAME: <2 x i32> [[X:%.*]]) {
256 ; EXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x double>
257 ; EXP2-NEXT:    [[MUL:%.*]] = fmul <2 x double> [[ITOFP]], <double 3.000000e+00, double 3.000000e+00>
258 ; EXP2-NEXT:    [[EXP2:%.*]] = tail call <2 x double> @llvm.exp2.v2f64(<2 x double> [[MUL]])
259 ; EXP2-NEXT:    ret <2 x double> [[EXP2]]
261 ; LDEXP-EXP2-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_8(
262 ; LDEXP-EXP2-SAME: <2 x i32> [[X:%.*]]) {
263 ; LDEXP-EXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x double>
264 ; LDEXP-EXP2-NEXT:    [[MUL:%.*]] = fmul <2 x double> [[ITOFP]], splat (double 3.000000e+00)
265 ; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call <2 x double> @llvm.exp2.v2f64(<2 x double> [[MUL]])
266 ; LDEXP-EXP2-NEXT:    ret <2 x double> [[EXP2]]
268 ; LDEXP-NOEXP2-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_8(
269 ; LDEXP-NOEXP2-SAME: <2 x i32> [[X:%.*]]) {
270 ; LDEXP-NOEXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x double>
271 ; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call <2 x double> @llvm.pow.v2f64(<2 x double> splat (double 8.000000e+00), <2 x double> [[ITOFP]])
272 ; LDEXP-NOEXP2-NEXT:    ret <2 x double> [[POW]]
274 ; NOLDEXP-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_8(
275 ; NOLDEXP-SAME: <2 x i32> [[X:%.*]]) {
276 ; NOLDEXP-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x double>
277 ; NOLDEXP-NEXT:    [[MUL:%.*]] = fmul <2 x double> [[ITOFP]], splat (double 3.000000e+00)
278 ; NOLDEXP-NEXT:    [[EXP2:%.*]] = tail call <2 x double> @llvm.exp2.v2f64(<2 x double> [[MUL]])
279 ; NOLDEXP-NEXT:    ret <2 x double> [[EXP2]]
281   %itofp = sitofp <2 x i32> %x to <2 x double>
282   %pow = tail call <2 x double> @llvm.pow.v2f64(<2 x double> <double 8.000000e+00, double 8.000000e+00>, <2 x double> %itofp)
283   ret <2 x double> %pow
286 define fp128 @pow_sitofp_fp128_const_base_2(i32 %x) {
287 ; CHECK-LABEL: define fp128 @pow_sitofp_fp128_const_base_2(
288 ; CHECK-SAME: i32 [[X:%.*]]) {
289 ; CHECK-NEXT:    [[EXP2:%.*]] = tail call fp128 @llvm.ldexp.f128.i32(fp128 0xL00000000000000003FFF000000000000, i32 [[X]])
290 ; CHECK-NEXT:    ret fp128 [[EXP2]]
292   %itofp = sitofp i32 %x to fp128
293   %pow = tail call fp128 @llvm.pow.fp128(fp128 0xL00000000000000004000000000000000, fp128 %itofp)
294   ret fp128 %pow
297 ; FIXME: This asserts
298 ; define bfloat @pow_sitofp_bf16_const_base_2(i32 %x) {
299 ;   %itofp = sitofp i32 %x to bfloat
300 ;   %pow = tail call bfloat @llvm.pow.bf16(bfloat 2.000000e+00, bfloat %itofp)
301 ;   ret bfloat %pow
302 ; }
304 ; FIXME: This asserts
305 ; define x86_fp80 @pow_sitofp_x86_fp80_const_base_2(i32 %x) {
306 ;   %itofp = sitofp i32 %x to x86_fp80
307 ;   %fp2 = fpext float 2.0 to x86_fp80
308 ;   %pow = tail call x86_fp80 @llvm.pow.f80(x86_fp80 %fp2, x86_fp80 %itofp)
309 ;   ret x86_fp80 %pow
310 ; }
312 ; FIXME: This asserts
313 ; define ppc_fp128 @pow_sitofp_ppc_fp128_const_base_2(i32 %x) {
314 ;   %itofp = sitofp i32 %x to ppc_fp128
315 ;   %fp2 = fpext float 2.0 to ppc_fp128
316 ;   %pow = tail call ppc_fp128 @llvm.pow.ppcf128(ppc_fp128 %fp2, ppc_fp128 %itofp)
317 ;   ret ppc_fp128 %pow
318 ; }
321 declare float @powf(float, float)
322 declare double @pow(double, double)
323 declare fp128 @powl(fp128, fp128)
325 define float @libcall_powf_sitofp_f32_const_base_2(i32 %x) {
326 ; LDEXP-LABEL: define float @libcall_powf_sitofp_f32_const_base_2(
327 ; LDEXP-SAME: i32 [[X:%.*]]) {
328 ; LDEXP-NEXT:    [[LDEXPF:%.*]] = tail call float @ldexpf(float 1.000000e+00, i32 [[X]])
329 ; LDEXP-NEXT:    ret float [[LDEXPF]]
331 ; NOLDEXP-LABEL: define float @libcall_powf_sitofp_f32_const_base_2(
332 ; NOLDEXP-SAME: i32 [[X:%.*]]) {
333 ; NOLDEXP-NEXT:    [[ITOFP:%.*]] = sitofp i32 [[X]] to float
334 ; NOLDEXP-NEXT:    [[EXP2F:%.*]] = tail call float @exp2f(float [[ITOFP]])
335 ; NOLDEXP-NEXT:    ret float [[EXP2F]]
337   %itofp = sitofp i32 %x to float
338   %pow = tail call float @powf(float 2.000000e+00, float %itofp)
339   ret float %pow
342 define float @libcall_powf_sitofp_f32_const_base_2__flags(i32 %x) {
343 ; LDEXP-LABEL: define float @libcall_powf_sitofp_f32_const_base_2__flags(
344 ; LDEXP-SAME: i32 [[X:%.*]]) {
345 ; LDEXP-NEXT:    [[LDEXPF:%.*]] = tail call nnan nsz float @ldexpf(float 1.000000e+00, i32 [[X]])
346 ; LDEXP-NEXT:    ret float [[LDEXPF]]
348 ; NOLDEXP-LABEL: define float @libcall_powf_sitofp_f32_const_base_2__flags(
349 ; NOLDEXP-SAME: i32 [[X:%.*]]) {
350 ; NOLDEXP-NEXT:    [[ITOFP:%.*]] = sitofp i32 [[X]] to float
351 ; NOLDEXP-NEXT:    [[EXP2F:%.*]] = tail call nnan nsz float @exp2f(float [[ITOFP]])
352 ; NOLDEXP-NEXT:    ret float [[EXP2F]]
354   %itofp = sitofp i32 %x to float
355   %pow = tail call nnan nsz float @powf(float 2.000000e+00, float %itofp)
356   ret float %pow
359 define float @readnone_libcall_powf_sitofp_f32_const_base_2(i32 %x) {
360 ; CHECK-LABEL: define float @readnone_libcall_powf_sitofp_f32_const_base_2(
361 ; CHECK-SAME: i32 [[X:%.*]]) {
362 ; CHECK-NEXT:    [[EXP2:%.*]] = tail call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[X]])
363 ; CHECK-NEXT:    ret float [[EXP2]]
365   %itofp = sitofp i32 %x to float
366   %pow = tail call float @powf(float 2.000000e+00, float %itofp) memory(none)
367   ret float %pow
370 define double @readnone_libcall_pow_sitofp_f32_const_base_2(i32 %x) {
371 ; CHECK-LABEL: define double @readnone_libcall_pow_sitofp_f32_const_base_2(
372 ; CHECK-SAME: i32 [[X:%.*]]) {
373 ; CHECK-NEXT:    [[EXP2:%.*]] = tail call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[X]])
374 ; CHECK-NEXT:    ret double [[EXP2]]
376   %itofp = sitofp i32 %x to double
377   %pow = tail call double @pow(double 2.000000e+00, double %itofp) memory(none)
378   ret double %pow
381 define fp128 @readnone_libcall_powl_sitofp_fp128_const_base_2(i32 %x) {
382 ; CHECK-LABEL: define fp128 @readnone_libcall_powl_sitofp_fp128_const_base_2(
383 ; CHECK-SAME: i32 [[X:%.*]]) {
384 ; CHECK-NEXT:    [[EXP2:%.*]] = tail call fp128 @llvm.ldexp.f128.i32(fp128 0xL00000000000000003FFF000000000000, i32 [[X]])
385 ; CHECK-NEXT:    ret fp128 [[EXP2]]
387   %itofp = sitofp i32 %x to fp128
388   %pow = tail call fp128 @powl(fp128 0xL00000000000000004000000000000000, fp128 %itofp) memory(none)
389   ret fp128 %pow