xref: /llvm-project/llvm/test/Transforms/InstCombine/exp2-1.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; Test that the exp2 library call simplifier works correctly.
3;
4; RUN: opt < %s -passes=instcombine -S -mtriple=unknown | FileCheck %s -check-prefixes=LDEXP32
5; RUN: opt < %s -passes=instcombine -S -mtriple=msp430 | FileCheck %s -check-prefixes=LDEXP16
6; RUN: opt < %s -passes=instcombine -S -mtriple=i386-pc-win32 | FileCheck %s -check-prefixes=NOLDEXPF
7; RUN: opt < %s -passes=instcombine -S -mtriple=i386-windows-gnu | FileCheck %s -check-prefixes=NOLDEXPF
8; RUN: opt < %s -passes=instcombine -S -mtriple=amdgcn-unknown-unknown | FileCheck %s -check-prefixes=NOLDEXP
9
10target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
11
12declare double @exp2(double)
13declare float @exp2f(float)
14declare double @llvm.exp2.f64(double)
15declare float @llvm.exp2.f32(float)
16declare <2 x float> @llvm.exp2.v2f32(<2 x float>)
17declare fp128 @exp2l(fp128)
18
19
20; Check exp2(sitofp(x)) -> ldexp(1.0, sext(x)).
21
22define double @test_simplify1(i32 %x) {
23; LDEXP32-LABEL: @test_simplify1(
24; LDEXP32-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[X:%.*]])
25; LDEXP32-NEXT:    ret double [[LDEXP]]
26;
27; LDEXP16-LABEL: @test_simplify1(
28; LDEXP16-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to double
29; LDEXP16-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
30; LDEXP16-NEXT:    ret double [[RET]]
31;
32; NOLDEXPF-LABEL: @test_simplify1(
33; NOLDEXPF-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[X:%.*]])
34; NOLDEXPF-NEXT:    ret double [[LDEXP]]
35;
36; NOLDEXP-LABEL: @test_simplify1(
37; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to double
38; NOLDEXP-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
39; NOLDEXP-NEXT:    ret double [[RET]]
40;
41  %conv = sitofp i32 %x to double
42  %ret = call double @exp2(double %conv)
43  ret double %ret
44}
45
46define double @test_simplify2(i16 signext %x) {
47; LDEXP32-LABEL: @test_simplify2(
48; LDEXP32-NEXT:    [[TMP1:%.*]] = sext i16 [[X:%.*]] to i32
49; LDEXP32-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
50; LDEXP32-NEXT:    ret double [[LDEXP]]
51;
52; LDEXP16-LABEL: @test_simplify2(
53; LDEXP16-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i16 [[X:%.*]])
54; LDEXP16-NEXT:    ret double [[LDEXP]]
55;
56; NOLDEXPF-LABEL: @test_simplify2(
57; NOLDEXPF-NEXT:    [[TMP1:%.*]] = sext i16 [[X:%.*]] to i32
58; NOLDEXPF-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
59; NOLDEXPF-NEXT:    ret double [[LDEXP]]
60;
61; NOLDEXP-LABEL: @test_simplify2(
62; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i16 [[X:%.*]] to double
63; NOLDEXP-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
64; NOLDEXP-NEXT:    ret double [[RET]]
65;
66  %conv = sitofp i16 %x to double
67  %ret = call double @exp2(double %conv)
68  ret double %ret
69}
70
71define double @test_simplify3(i8 signext %x) {
72; LDEXP32-LABEL: @test_simplify3(
73; LDEXP32-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
74; LDEXP32-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
75; LDEXP32-NEXT:    ret double [[LDEXP]]
76;
77; LDEXP16-LABEL: @test_simplify3(
78; LDEXP16-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i16
79; LDEXP16-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i16 [[TMP1]])
80; LDEXP16-NEXT:    ret double [[LDEXP]]
81;
82; NOLDEXPF-LABEL: @test_simplify3(
83; NOLDEXPF-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
84; NOLDEXPF-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
85; NOLDEXPF-NEXT:    ret double [[LDEXP]]
86;
87; NOLDEXP-LABEL: @test_simplify3(
88; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i8 [[X:%.*]] to double
89; NOLDEXP-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
90; NOLDEXP-NEXT:    ret double [[RET]]
91;
92  %conv = sitofp i8 %x to double
93  %ret = call double @exp2(double %conv)
94  ret double %ret
95}
96
97define float @test_simplify4(i32 %x) {
98; LDEXP32-LABEL: @test_simplify4(
99; LDEXP32-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i32 [[X:%.*]])
100; LDEXP32-NEXT:    ret float [[LDEXPF]]
101;
102; LDEXP16-LABEL: @test_simplify4(
103; LDEXP16-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
104; LDEXP16-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]])
105; LDEXP16-NEXT:    ret float [[RET]]
106;
107; NOLDEXPF-LABEL: @test_simplify4(
108; NOLDEXPF-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
109; NOLDEXPF-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]])
110; NOLDEXPF-NEXT:    ret float [[RET]]
111;
112; NOLDEXP-LABEL: @test_simplify4(
113; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
114; NOLDEXP-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]])
115; NOLDEXP-NEXT:    ret float [[RET]]
116;
117  %conv = sitofp i32 %x to float
118  %ret = call float @exp2f(float %conv)
119  ret float %ret
120}
121
122; Check exp2(uitofp(x)) -> ldexp(1.0, zext(x)).
123
124define double @test_no_simplify1(i32 %x) {
125; LDEXP32-LABEL: @test_no_simplify1(
126; LDEXP32-NEXT:    [[CONV:%.*]] = uitofp i32 [[X:%.*]] to double
127; LDEXP32-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
128; LDEXP32-NEXT:    ret double [[RET]]
129;
130; LDEXP16-LABEL: @test_no_simplify1(
131; LDEXP16-NEXT:    [[CONV:%.*]] = uitofp i32 [[X:%.*]] to double
132; LDEXP16-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
133; LDEXP16-NEXT:    ret double [[RET]]
134;
135; NOLDEXPF-LABEL: @test_no_simplify1(
136; NOLDEXPF-NEXT:    [[CONV:%.*]] = uitofp i32 [[X:%.*]] to double
137; NOLDEXPF-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
138; NOLDEXPF-NEXT:    ret double [[RET]]
139;
140; NOLDEXP-LABEL: @test_no_simplify1(
141; NOLDEXP-NEXT:    [[CONV:%.*]] = uitofp i32 [[X:%.*]] to double
142; NOLDEXP-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
143; NOLDEXP-NEXT:    ret double [[RET]]
144;
145  %conv = uitofp i32 %x to double
146  %ret = call double @exp2(double %conv)
147  ret double %ret
148}
149
150define double @test_simplify6(i16 zeroext %x) {
151; LDEXP32-LABEL: @test_simplify6(
152; LDEXP32-NEXT:    [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32
153; LDEXP32-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
154; LDEXP32-NEXT:    ret double [[LDEXP]]
155;
156; LDEXP16-LABEL: @test_simplify6(
157; LDEXP16-NEXT:    [[CONV:%.*]] = uitofp i16 [[X:%.*]] to double
158; LDEXP16-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
159; LDEXP16-NEXT:    ret double [[RET]]
160;
161; NOLDEXPF-LABEL: @test_simplify6(
162; NOLDEXPF-NEXT:    [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32
163; NOLDEXPF-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
164; NOLDEXPF-NEXT:    ret double [[LDEXP]]
165;
166; NOLDEXP-LABEL: @test_simplify6(
167; NOLDEXP-NEXT:    [[CONV:%.*]] = uitofp i16 [[X:%.*]] to double
168; NOLDEXP-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
169; NOLDEXP-NEXT:    ret double [[RET]]
170;
171  %conv = uitofp i16 %x to double
172  %ret = call double @exp2(double %conv)
173  ret double %ret
174}
175
176define double @test_simplify7(i8 zeroext %x) {
177; LDEXP32-LABEL: @test_simplify7(
178; LDEXP32-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
179; LDEXP32-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
180; LDEXP32-NEXT:    ret double [[LDEXP]]
181;
182; LDEXP16-LABEL: @test_simplify7(
183; LDEXP16-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i16
184; LDEXP16-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i16 [[TMP1]])
185; LDEXP16-NEXT:    ret double [[LDEXP]]
186;
187; NOLDEXPF-LABEL: @test_simplify7(
188; NOLDEXPF-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
189; NOLDEXPF-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
190; NOLDEXPF-NEXT:    ret double [[LDEXP]]
191;
192; NOLDEXP-LABEL: @test_simplify7(
193; NOLDEXP-NEXT:    [[CONV:%.*]] = uitofp i8 [[X:%.*]] to double
194; NOLDEXP-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]])
195; NOLDEXP-NEXT:    ret double [[RET]]
196;
197  %conv = uitofp i8 %x to double
198  %ret = call double @exp2(double %conv)
199  ret double %ret
200}
201
202define float @test_simplify8(i8 zeroext %x) {
203; LDEXP32-LABEL: @test_simplify8(
204; LDEXP32-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
205; LDEXP32-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i32 [[TMP1]])
206; LDEXP32-NEXT:    ret float [[LDEXPF]]
207;
208; LDEXP16-LABEL: @test_simplify8(
209; LDEXP16-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i16
210; LDEXP16-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i16 [[TMP1]])
211; LDEXP16-NEXT:    ret float [[LDEXPF]]
212;
213; NOLDEXPF-LABEL: @test_simplify8(
214; NOLDEXPF-NEXT:    [[CONV:%.*]] = uitofp i8 [[X:%.*]] to float
215; NOLDEXPF-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]])
216; NOLDEXPF-NEXT:    ret float [[RET]]
217;
218; NOLDEXP-LABEL: @test_simplify8(
219; NOLDEXP-NEXT:    [[CONV:%.*]] = uitofp i8 [[X:%.*]] to float
220; NOLDEXP-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]])
221; NOLDEXP-NEXT:    ret float [[RET]]
222;
223  %conv = uitofp i8 %x to float
224  %ret = call float @exp2f(float %conv)
225  ret float %ret
226}
227
228define double @test_simplify9(i8 zeroext %x) {
229; LDEXP32-LABEL: @test_simplify9(
230; LDEXP32-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
231; LDEXP32-NEXT:    [[RET:%.*]] = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[TMP1]])
232; LDEXP32-NEXT:    ret double [[RET]]
233;
234; LDEXP16-LABEL: @test_simplify9(
235; LDEXP16-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i16
236; LDEXP16-NEXT:    [[RET:%.*]] = call double @llvm.ldexp.f64.i16(double 1.000000e+00, i16 [[TMP1]])
237; LDEXP16-NEXT:    ret double [[RET]]
238;
239; NOLDEXPF-LABEL: @test_simplify9(
240; NOLDEXPF-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
241; NOLDEXPF-NEXT:    [[RET:%.*]] = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[TMP1]])
242; NOLDEXPF-NEXT:    ret double [[RET]]
243;
244; NOLDEXP-LABEL: @test_simplify9(
245; NOLDEXP-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
246; NOLDEXP-NEXT:    [[RET:%.*]] = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[TMP1]])
247; NOLDEXP-NEXT:    ret double [[RET]]
248;
249  %conv = uitofp i8 %x to double
250  %ret = call double @llvm.exp2.f64(double %conv)
251  ret double %ret
252}
253
254define float @test_simplify10(i8 zeroext %x) {
255; LDEXP32-LABEL: @test_simplify10(
256; LDEXP32-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
257; LDEXP32-NEXT:    [[RET:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
258; LDEXP32-NEXT:    ret float [[RET]]
259;
260; LDEXP16-LABEL: @test_simplify10(
261; LDEXP16-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i16
262; LDEXP16-NEXT:    [[RET:%.*]] = call float @llvm.ldexp.f32.i16(float 1.000000e+00, i16 [[TMP1]])
263; LDEXP16-NEXT:    ret float [[RET]]
264;
265; NOLDEXPF-LABEL: @test_simplify10(
266; NOLDEXPF-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
267; NOLDEXPF-NEXT:    [[RET:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
268; NOLDEXPF-NEXT:    ret float [[RET]]
269;
270; NOLDEXP-LABEL: @test_simplify10(
271; NOLDEXP-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
272; NOLDEXP-NEXT:    [[RET:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
273; NOLDEXP-NEXT:    ret float [[RET]]
274;
275  %conv = uitofp i8 %x to float
276  %ret = call float @llvm.exp2.f32(float %conv)
277  ret float %ret
278}
279
280define float @sitofp_scalar_intrinsic_with_FMF(i8 %x) {
281; LDEXP32-LABEL: @sitofp_scalar_intrinsic_with_FMF(
282; LDEXP32-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
283; LDEXP32-NEXT:    [[R:%.*]] = tail call nnan float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
284; LDEXP32-NEXT:    ret float [[R]]
285;
286; LDEXP16-LABEL: @sitofp_scalar_intrinsic_with_FMF(
287; LDEXP16-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i16
288; LDEXP16-NEXT:    [[R:%.*]] = tail call nnan float @llvm.ldexp.f32.i16(float 1.000000e+00, i16 [[TMP1]])
289; LDEXP16-NEXT:    ret float [[R]]
290;
291; NOLDEXPF-LABEL: @sitofp_scalar_intrinsic_with_FMF(
292; NOLDEXPF-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
293; NOLDEXPF-NEXT:    [[R:%.*]] = tail call nnan float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
294; NOLDEXPF-NEXT:    ret float [[R]]
295;
296; NOLDEXP-LABEL: @sitofp_scalar_intrinsic_with_FMF(
297; NOLDEXP-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
298; NOLDEXP-NEXT:    [[R:%.*]] = tail call nnan float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
299; NOLDEXP-NEXT:    ret float [[R]]
300;
301  %s = sitofp i8 %x to float
302  %r = tail call nnan float @llvm.exp2.f32(float %s)
303  ret float %r
304}
305
306; PR60605
307; This would crash because there is no ldexp intrinsic.
308
309define <2 x float> @sitofp_vector_intrinsic_with_FMF(<2 x i8> %x) {
310; LDEXP32-LABEL: @sitofp_vector_intrinsic_with_FMF(
311; LDEXP32-NEXT:    [[TMP1:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i32>
312; LDEXP32-NEXT:    [[R:%.*]] = call nnan <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> splat (float 1.000000e+00), <2 x i32> [[TMP1]])
313; LDEXP32-NEXT:    ret <2 x float> [[R]]
314;
315; LDEXP16-LABEL: @sitofp_vector_intrinsic_with_FMF(
316; LDEXP16-NEXT:    [[TMP1:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i16>
317; LDEXP16-NEXT:    [[R:%.*]] = call nnan <2 x float> @llvm.ldexp.v2f32.v2i16(<2 x float> splat (float 1.000000e+00), <2 x i16> [[TMP1]])
318; LDEXP16-NEXT:    ret <2 x float> [[R]]
319;
320; NOLDEXPF-LABEL: @sitofp_vector_intrinsic_with_FMF(
321; NOLDEXPF-NEXT:    [[TMP1:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i32>
322; NOLDEXPF-NEXT:    [[R:%.*]] = call nnan <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> splat (float 1.000000e+00), <2 x i32> [[TMP1]])
323; NOLDEXPF-NEXT:    ret <2 x float> [[R]]
324;
325; NOLDEXP-LABEL: @sitofp_vector_intrinsic_with_FMF(
326; NOLDEXP-NEXT:    [[TMP1:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i32>
327; NOLDEXP-NEXT:    [[R:%.*]] = call nnan <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> splat (float 1.000000e+00), <2 x i32> [[TMP1]])
328; NOLDEXP-NEXT:    ret <2 x float> [[R]]
329;
330  %s = sitofp <2 x i8> %x to <2 x float>
331  %r = call nnan <2 x float> @llvm.exp2.v2f32(<2 x float> %s)
332  ret <2 x float> %r
333}
334
335define double @test_readonly_exp2_f64_of_sitofp(i32 %x) {
336; LDEXP32-LABEL: @test_readonly_exp2_f64_of_sitofp(
337; LDEXP32-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[X:%.*]])
338; LDEXP32-NEXT:    ret double [[LDEXP]]
339;
340; LDEXP16-LABEL: @test_readonly_exp2_f64_of_sitofp(
341; LDEXP16-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to double
342; LDEXP16-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]]) #[[ATTR2:[0-9]+]]
343; LDEXP16-NEXT:    ret double [[RET]]
344;
345; NOLDEXPF-LABEL: @test_readonly_exp2_f64_of_sitofp(
346; NOLDEXPF-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[X:%.*]])
347; NOLDEXPF-NEXT:    ret double [[LDEXP]]
348;
349; NOLDEXP-LABEL: @test_readonly_exp2_f64_of_sitofp(
350; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to double
351; NOLDEXP-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]]) #[[ATTR1:[0-9]+]]
352; NOLDEXP-NEXT:    ret double [[RET]]
353;
354  %conv = sitofp i32 %x to double
355  %ret = call double @exp2(double %conv) readonly
356  ret double %ret
357}
358
359define float @test_readonly_exp2f_f32_of_sitofp(i32 %x) {
360; LDEXP32-LABEL: @test_readonly_exp2f_f32_of_sitofp(
361; LDEXP32-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i32 [[X:%.*]])
362; LDEXP32-NEXT:    ret float [[LDEXPF]]
363;
364; LDEXP16-LABEL: @test_readonly_exp2f_f32_of_sitofp(
365; LDEXP16-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
366; LDEXP16-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]]) #[[ATTR2]]
367; LDEXP16-NEXT:    ret float [[RET]]
368;
369; NOLDEXPF-LABEL: @test_readonly_exp2f_f32_of_sitofp(
370; NOLDEXPF-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
371; NOLDEXPF-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]]) #[[ATTR2:[0-9]+]]
372; NOLDEXPF-NEXT:    ret float [[RET]]
373;
374; NOLDEXP-LABEL: @test_readonly_exp2f_f32_of_sitofp(
375; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
376; NOLDEXP-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]]) #[[ATTR1]]
377; NOLDEXP-NEXT:    ret float [[RET]]
378;
379  %conv = sitofp i32 %x to float
380  %ret = call float @exp2f(float %conv) readonly
381  ret float %ret
382}
383
384define fp128 @test_readonly_exp2l_fp128_of_sitofp(i32 %x) {
385; LDEXP32-LABEL: @test_readonly_exp2l_fp128_of_sitofp(
386; LDEXP32-NEXT:    [[LDEXPL:%.*]] = call fp128 @ldexpl(fp128 0xL00000000000000003FFF000000000000, i32 [[X:%.*]])
387; LDEXP32-NEXT:    ret fp128 [[LDEXPL]]
388;
389; LDEXP16-LABEL: @test_readonly_exp2l_fp128_of_sitofp(
390; LDEXP16-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to fp128
391; LDEXP16-NEXT:    [[RET:%.*]] = call fp128 @exp2l(fp128 [[CONV]]) #[[ATTR2]]
392; LDEXP16-NEXT:    ret fp128 [[RET]]
393;
394; NOLDEXP-LABEL: @test_readonly_exp2l_fp128_of_sitofp(
395; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to fp128
396; NOLDEXP-NEXT:    [[RET:%.*]] = call fp128 @exp2l(fp128 [[CONV]]) #[[ATTR1]]
397; NOLDEXP-NEXT:    ret fp128 [[RET]]
398;
399  %conv = sitofp i32 %x to fp128
400  %ret = call fp128 @exp2l(fp128 %conv) readonly
401  ret fp128 %ret
402}
403
404define float @test_readonly_exp2f_f32_of_sitofp_flags(i32 %x) {
405; LDEXP32-LABEL: @test_readonly_exp2f_f32_of_sitofp_flags(
406; LDEXP32-NEXT:    [[LDEXPF:%.*]] = call nnan ninf float @ldexpf(float 1.000000e+00, i32 [[X:%.*]])
407; LDEXP32-NEXT:    ret float [[LDEXPF]]
408;
409; LDEXP16-LABEL: @test_readonly_exp2f_f32_of_sitofp_flags(
410; LDEXP16-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
411; LDEXP16-NEXT:    [[RET:%.*]] = call nnan ninf float @exp2f(float [[CONV]]) #[[ATTR2]]
412; LDEXP16-NEXT:    ret float [[RET]]
413;
414; NOLDEXPF-LABEL: @test_readonly_exp2f_f32_of_sitofp_flags(
415; NOLDEXPF-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
416; NOLDEXPF-NEXT:    [[RET:%.*]] = call nnan ninf float @exp2f(float [[CONV]]) #[[ATTR2]]
417; NOLDEXPF-NEXT:    ret float [[RET]]
418;
419; NOLDEXP-LABEL: @test_readonly_exp2f_f32_of_sitofp_flags(
420; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
421; NOLDEXP-NEXT:    [[RET:%.*]] = call nnan ninf float @exp2f(float [[CONV]]) #[[ATTR1]]
422; NOLDEXP-NEXT:    ret float [[RET]]
423;
424  %conv = sitofp i32 %x to float
425  %ret = call nnan ninf float @exp2f(float %conv) readonly
426  ret float %ret
427}
428