xref: /llvm-project/llvm/test/Transforms/InstCombine/pow-to-ldexp.ll (revision 56c091ea7106507b36015297ee9005c9d5fab0bf)
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
5
6
7define 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]]
12;
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
16}
17
18define 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]]
23;
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
27}
28
29define 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]]
35;
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]]
41;
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]]
47;
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
51}
52
53define 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]]
60;
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]]
66;
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]]
73;
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
77}
78
79define 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]]
86;
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]]
92;
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]]
99;
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
103}
104
105define 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]]
110;
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
114}
115
116define 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]]
121;
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
125}
126
127define <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]]
132;
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
136}
137
138define <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]]
145;
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]]
151;
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]]
158;
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
162}
163
164define <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]]
170;
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
174}
175
176define <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]]
181;
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
185}
186
187define <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> splat (float 1.000000e+00), <vscale x 4 x i32> [[X]])
191; CHECK-NEXT:    ret <vscale x 4 x float> [[EXP2]]
192;
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
196}
197
198define <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]]
203;
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
207}
208
209define <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]]
214;
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
218}
219
220define <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]]
227;
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]]
234;
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]]
240;
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]]
247;
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
251}
252
253define <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]]
260;
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]]
267;
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]]
273;
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]]
280;
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
284}
285
286define 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]]
291;
292  %itofp = sitofp i32 %x to fp128
293  %pow = tail call fp128 @llvm.pow.fp128(fp128 0xL00000000000000004000000000000000, fp128 %itofp)
294  ret fp128 %pow
295}
296
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; }
303
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; }
311
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; }
319
320
321declare float @powf(float, float)
322declare double @pow(double, double)
323declare fp128 @powl(fp128, fp128)
324
325define 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]]
330;
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]]
336;
337  %itofp = sitofp i32 %x to float
338  %pow = tail call float @powf(float 2.000000e+00, float %itofp)
339  ret float %pow
340}
341
342define 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]]
347;
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]]
353;
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
357}
358
359define 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]]
364;
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
368}
369
370define 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]]
375;
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
379}
380
381define 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]]
386;
387  %itofp = sitofp i32 %x to fp128
388  %pow = tail call fp128 @powl(fp128 0xL00000000000000004000000000000000, fp128 %itofp) memory(none)
389  ret fp128 %pow
390}
391