xref: /llvm-project/llvm/test/Transforms/InstCombine/ldexp.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3
4declare float @llvm.ldexp.f32.i32(float, i32)
5declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float>, <2 x i32>)
6declare float @llvm.ldexp.f32.i64(float, i64)
7
8; select c, (ldexp val, e0), (ldexp val, e1) -> ldexp val, (select c, e0, e1)
9define float @select_ldexp_f32_sameval_differentexp(i1 %cond, float %val, i32 %exp0, i32 %exp1) {
10; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp
11; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]]) {
12; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]]
13; CHECK-NEXT:    [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[TMP1]])
14; CHECK-NEXT:    ret float [[SELECT]]
15;
16  %ldexp0 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp0)
17  %ldexp1 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp1)
18  %select = select i1 %cond, float %ldexp0, float %ldexp1
19  ret float %select
20}
21
22define float @select_ldexp_f32_sameval_differentexp_selectflags(i1 %cond, float %val, i32 %exp0, i32 %exp1) {
23; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp_selectflags
24; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]]) {
25; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]]
26; CHECK-NEXT:    [[SELECT:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[TMP1]])
27; CHECK-NEXT:    ret float [[SELECT]]
28;
29  %ldexp0 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp0)
30  %ldexp1 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp1)
31  %select = select nnan i1 %cond, float %ldexp0, float %ldexp1
32  ret float %select
33}
34
35define float @select_ldexp_f32_sameval_differentexp_ldexp_intersect_flags(i1 %cond, float %val, i32 %exp0, i32 %exp1) {
36; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp_ldexp_intersect_flags
37; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]]) {
38; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]]
39; CHECK-NEXT:    [[SELECT:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[TMP1]])
40; CHECK-NEXT:    ret float [[SELECT]]
41;
42  %ldexp0 = call nnan nsz float @llvm.ldexp.f32.i32(float %val, i32 %exp0)
43  %ldexp1 = call nnan float @llvm.ldexp.f32.i32(float %val, i32 %exp1)
44  %select = select i1 %cond, float %ldexp0, float %ldexp1
45  ret float %select
46}
47
48define float @select_ldexp_f32_sameval_differentexp_ldexp_intersect_flags_union_select(i1 %cond, float %val, i32 %exp0, i32 %exp1) {
49; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp_ldexp_intersect_flags_union_select
50; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]]) {
51; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]]
52; CHECK-NEXT:    [[SELECT:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[TMP1]])
53; CHECK-NEXT:    ret float [[SELECT]]
54;
55  %ldexp0 = call nnan nsz float @llvm.ldexp.f32.i32(float %val, i32 %exp0)
56  %ldexp1 = call nnan float @llvm.ldexp.f32.i32(float %val, i32 %exp1)
57  %select = select ninf i1 %cond, float %ldexp0, float %ldexp1
58  ret float %select
59}
60
61define float @select_ldexp_f32_sameval_differentexp_multiuse0(i1 %cond, float %val, i32 %exp0, i32 %exp1, ptr %ptr) {
62; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp_multiuse0
63; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]], ptr [[PTR:%.*]]) {
64; CHECK-NEXT:    [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[EXP0]])
65; CHECK-NEXT:    store float [[LDEXP0]], ptr [[PTR]], align 4
66; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]]
67; CHECK-NEXT:    [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[TMP1]])
68; CHECK-NEXT:    ret float [[SELECT]]
69;
70  %ldexp0 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp0)
71  store float %ldexp0, ptr %ptr
72  %ldexp1 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp1)
73  %select = select i1 %cond, float %ldexp0, float %ldexp1
74  ret float %select
75}
76
77define float @select_ldexp_f32_sameval_differentexp_multiuse1(i1 %cond, float %val, i32 %exp0, i32 %exp1, ptr %ptr) {
78; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp_multiuse1
79; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]], ptr [[PTR:%.*]]) {
80; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[EXP1]])
81; CHECK-NEXT:    store float [[LDEXP1]], ptr [[PTR]], align 4
82; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]]
83; CHECK-NEXT:    [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[TMP1]])
84; CHECK-NEXT:    ret float [[SELECT]]
85;
86  %ldexp0 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp0)
87  %ldexp1 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp1)
88  store float %ldexp1, ptr %ptr
89  %select = select i1 %cond, float %ldexp0, float %ldexp1
90  ret float %select
91}
92
93define float @select_ldexp_f32_sameval_differentexp_multiuse_both(i1 %cond, float %val, i32 %exp0, i32 %exp1, ptr %ptr0, ptr %ptr1) {
94; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp_multiuse_both
95; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]], ptr [[PTR0:%.*]], ptr [[PTR1:%.*]]) {
96; CHECK-NEXT:    [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[EXP0]])
97; CHECK-NEXT:    store float [[LDEXP0]], ptr [[PTR0]], align 4
98; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[EXP1]])
99; CHECK-NEXT:    store float [[LDEXP1]], ptr [[PTR1]], align 4
100; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[LDEXP0]], float [[LDEXP1]]
101; CHECK-NEXT:    ret float [[SELECT]]
102;
103  %ldexp0 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp0)
104  store float %ldexp0, ptr %ptr0
105  %ldexp1 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp1)
106  store float %ldexp1, ptr %ptr1
107  %select = select i1 %cond, float %ldexp0, float %ldexp1
108  ret float %select
109}
110
111; select c, (ldexp val0, e), (ldexp val1, ee) -> ldexp (select c, val0, val1), e
112define float @select_ldexp_f32_differentval_sameexp(i1 %cond, float %val0, float %val1, i32 %exp) {
113; CHECK-LABEL: define float @select_ldexp_f32_differentval_sameexp
114; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP:%.*]]) {
115; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]]
116; CHECK-NEXT:    [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[EXP]])
117; CHECK-NEXT:    ret float [[SELECT]]
118;
119  %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp)
120  %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp)
121  %select = select i1 %cond, float %ldexp0, float %ldexp1
122  ret float %select
123}
124
125define float @select_ldexp_f32_differentval_sameexp_selectflags(i1 %cond, float %val0, float %val1, i32 %exp) {
126; CHECK-LABEL: define float @select_ldexp_f32_differentval_sameexp_selectflags
127; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP:%.*]]) {
128; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]]
129; CHECK-NEXT:    [[SELECT:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[EXP]])
130; CHECK-NEXT:    ret float [[SELECT]]
131;
132  %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp)
133  %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp)
134  %select = select nnan i1 %cond, float %ldexp0, float %ldexp1
135  ret float %select
136}
137
138define float @select_ldexp_f32_differentval_sameexp_ldexp_intersect_flags(i1 %cond, float %val0, float %val1, i32 %exp) {
139; CHECK-LABEL: define float @select_ldexp_f32_differentval_sameexp_ldexp_intersect_flags
140; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP:%.*]]) {
141; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]]
142; CHECK-NEXT:    [[SELECT:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[EXP]])
143; CHECK-NEXT:    ret float [[SELECT]]
144;
145  %ldexp0 = call nnan nsz float @llvm.ldexp.f32.i32(float %val0, i32 %exp)
146  %ldexp1 = call nnan float @llvm.ldexp.f32.i32(float %val1, i32 %exp)
147  %select = select i1 %cond, float %ldexp0, float %ldexp1
148  ret float %select
149}
150
151define float @select_ldexp_f32_differentval_sameexp_ldexp_intersect_flags_unino_select(i1 %cond, float %val0, float %val1, i32 %exp) {
152; CHECK-LABEL: define float @select_ldexp_f32_differentval_sameexp_ldexp_intersect_flags_unino_select
153; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP:%.*]]) {
154; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]]
155; CHECK-NEXT:    [[SELECT:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[EXP]])
156; CHECK-NEXT:    ret float [[SELECT]]
157;
158  %ldexp0 = call nnan nsz float @llvm.ldexp.f32.i32(float %val0, i32 %exp)
159  %ldexp1 = call nnan float @llvm.ldexp.f32.i32(float %val1, i32 %exp)
160  %select = select ninf i1 %cond, float %ldexp0, float %ldexp1
161  ret float %select
162}
163
164define float @select_ldexp_f32_differentval_sameexp_multiuse0(i1 %cond, float %val0, float %val1, i32 %exp, ptr %ptr) {
165; CHECK-LABEL: define float @select_ldexp_f32_differentval_sameexp_multiuse0
166; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP:%.*]], ptr [[PTR:%.*]]) {
167; CHECK-NEXT:    [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL0]], i32 [[EXP]])
168; CHECK-NEXT:    store float [[LDEXP0]], ptr [[PTR]], align 4
169; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]]
170; CHECK-NEXT:    [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[EXP]])
171; CHECK-NEXT:    ret float [[SELECT]]
172;
173  %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp)
174  store float %ldexp0, ptr %ptr
175  %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp)
176  %select = select i1 %cond, float %ldexp0, float %ldexp1
177  ret float %select
178}
179
180define float @select_ldexp_f32_differentval_sameexp_multiuse1(i1 %cond, float %val0, float %val1, i32 %exp, ptr %ptr) {
181; CHECK-LABEL: define float @select_ldexp_f32_differentval_sameexp_multiuse1
182; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP:%.*]], ptr [[PTR:%.*]]) {
183; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL1]], i32 [[EXP]])
184; CHECK-NEXT:    store float [[LDEXP1]], ptr [[PTR]], align 4
185; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]]
186; CHECK-NEXT:    [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[EXP]])
187; CHECK-NEXT:    ret float [[SELECT]]
188;
189  %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp)
190  %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp)
191  store float %ldexp1, ptr %ptr
192  %select = select i1 %cond, float %ldexp0, float %ldexp1
193  ret float %select
194}
195
196define float @select_ldexp_f32_differentval_differentexp(i1 %cond, float %val0, float %val1, i32 %exp0, i32 %exp1) {
197; CHECK-LABEL: define float @select_ldexp_f32_differentval_differentexp
198; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]]) {
199; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]]
200; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]]
201; CHECK-NEXT:    [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[TMP2]])
202; CHECK-NEXT:    ret float [[SELECT]]
203;
204  %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp0)
205  %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp1)
206  %select = select i1 %cond, float %ldexp0, float %ldexp1
207  ret float %select
208}
209
210define float @select_ldexp_f32_differentval_differentexp_multiuse0(i1 %cond, float %val0, float %val1, i32 %exp0, i32 %exp1, ptr %ptr) {
211; CHECK-LABEL: define float @select_ldexp_f32_differentval_differentexp_multiuse0
212; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]], ptr [[PTR:%.*]]) {
213; CHECK-NEXT:    [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL0]], i32 [[EXP0]])
214; CHECK-NEXT:    store float [[LDEXP0]], ptr [[PTR]], align 4
215; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]]
216; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]]
217; CHECK-NEXT:    [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[TMP2]])
218; CHECK-NEXT:    ret float [[SELECT]]
219;
220  %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp0)
221  store float %ldexp0, ptr %ptr
222  %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp1)
223  %select = select i1 %cond, float %ldexp0, float %ldexp1
224  ret float %select
225}
226
227define float @select_ldexp_f32_differentval_differentexp_multiuse1(i1 %cond, float %val0, float %val1, i32 %exp0, i32 %exp1, ptr %ptr) {
228; CHECK-LABEL: define float @select_ldexp_f32_differentval_differentexp_multiuse1
229; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]], ptr [[PTR:%.*]]) {
230; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL1]], i32 [[EXP1]])
231; CHECK-NEXT:    store float [[LDEXP1]], ptr [[PTR]], align 4
232; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], float [[VAL0]], float [[VAL1]]
233; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[COND]], i32 [[EXP0]], i32 [[EXP1]]
234; CHECK-NEXT:    [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[TMP1]], i32 [[TMP2]])
235; CHECK-NEXT:    ret float [[SELECT]]
236;
237  %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp0)
238  %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp1)
239  store float %ldexp1, ptr %ptr
240  %select = select i1 %cond, float %ldexp0, float %ldexp1
241  ret float %select
242}
243
244define float @select_ldexp_f32_differentval_differentexp_multiuse_both(i1 %cond, float %val0, float %val1, i32 %exp0, i32 %exp1, ptr %ptr0, ptr %ptr1) {
245; CHECK-LABEL: define float @select_ldexp_f32_differentval_differentexp_multiuse_both
246; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL0:%.*]], float [[VAL1:%.*]], i32 [[EXP0:%.*]], i32 [[EXP1:%.*]], ptr [[PTR0:%.*]], ptr [[PTR1:%.*]]) {
247; CHECK-NEXT:    [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL0]], i32 [[EXP0]])
248; CHECK-NEXT:    store float [[LDEXP0]], ptr [[PTR0]], align 4
249; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL1]], i32 [[EXP1]])
250; CHECK-NEXT:    store float [[LDEXP1]], ptr [[PTR1]], align 4
251; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[LDEXP0]], float [[LDEXP1]]
252; CHECK-NEXT:    ret float [[SELECT]]
253;
254  %ldexp0 = call float @llvm.ldexp.f32.i32(float %val0, i32 %exp0)
255  store float %ldexp0, ptr %ptr0
256  %ldexp1 = call float @llvm.ldexp.f32.i32(float %val1, i32 %exp1)
257  store float %ldexp1, ptr %ptr1
258  %select = select i1 %cond, float %ldexp0, float %ldexp1
259  ret float %select
260}
261
262define <2 x float> @select_ldexp_v2f32_sameval_differentexp(<2 x i1> %cond, <2 x float> %val, <2 x i32> %exp0, <2 x i32> %exp1) {
263; CHECK-LABEL: define <2 x float> @select_ldexp_v2f32_sameval_differentexp
264; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[VAL:%.*]], <2 x i32> [[EXP0:%.*]], <2 x i32> [[EXP1:%.*]]) {
265; CHECK-NEXT:    [[TMP1:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[EXP0]], <2 x i32> [[EXP1]]
266; CHECK-NEXT:    [[SELECT:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[VAL]], <2 x i32> [[TMP1]])
267; CHECK-NEXT:    ret <2 x float> [[SELECT]]
268;
269  %ldexp0 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val, <2 x i32> %exp0)
270  %ldexp1 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val, <2 x i32> %exp1)
271  %select = select <2 x i1> %cond, <2 x float> %ldexp0, <2 x float> %ldexp1
272  ret <2 x float> %select
273}
274
275define <2 x float> @select_ldexp_v2f32_differentval_sameexp(<2 x i1> %cond, <2 x float> %val0, <2 x float> %val1, <2 x i32> %exp) {
276; CHECK-LABEL: define <2 x float> @select_ldexp_v2f32_differentval_sameexp
277; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[VAL0:%.*]], <2 x float> [[VAL1:%.*]], <2 x i32> [[EXP:%.*]]) {
278; CHECK-NEXT:    [[TMP1:%.*]] = select <2 x i1> [[COND]], <2 x float> [[VAL0]], <2 x float> [[VAL1]]
279; CHECK-NEXT:    [[SELECT:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[TMP1]], <2 x i32> [[EXP]])
280; CHECK-NEXT:    ret <2 x float> [[SELECT]]
281;
282  %ldexp0 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val0, <2 x i32> %exp)
283  %ldexp1 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val1, <2 x i32> %exp)
284  %select = select <2 x i1> %cond, <2 x float> %ldexp0, <2 x float> %ldexp1
285  ret <2 x float> %select
286}
287
288define <2 x float> @select_ldexp_v2f32_differentval_differentexp(<2 x i1> %cond, <2 x float> %val0, <2 x float> %val1, <2 x i32> %exp0, <2 x i32> %exp1) {
289; CHECK-LABEL: define <2 x float> @select_ldexp_v2f32_differentval_differentexp
290; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[VAL0:%.*]], <2 x float> [[VAL1:%.*]], <2 x i32> [[EXP0:%.*]], <2 x i32> [[EXP1:%.*]]) {
291; CHECK-NEXT:    [[TMP1:%.*]] = select <2 x i1> [[COND]], <2 x float> [[VAL0]], <2 x float> [[VAL1]]
292; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[COND]], <2 x i32> [[EXP0]], <2 x i32> [[EXP1]]
293; CHECK-NEXT:    [[SELECT:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[TMP1]], <2 x i32> [[TMP2]])
294; CHECK-NEXT:    ret <2 x float> [[SELECT]]
295;
296  %ldexp0 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val0, <2 x i32> %exp0)
297  %ldexp1 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val1, <2 x i32> %exp1)
298  %select = select <2 x i1> %cond, <2 x float> %ldexp0, <2 x float> %ldexp1
299  ret <2 x float> %select
300}
301
302define float @select_ldexp_f32_same(i1 %cond, float %val, i32 %exp) {
303; CHECK-LABEL: define float @select_ldexp_f32_same
304; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP:%.*]]) {
305; CHECK-NEXT:    [[SELECT:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[EXP]])
306; CHECK-NEXT:    ret float [[SELECT]]
307;
308  %ldexp0 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp)
309  %ldexp1 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp)
310  %select = select i1 %cond, float %ldexp0, float %ldexp1
311  ret float %select
312}
313
314define float @select_ldexp_f32_sameval_differentexp_types(i1 %cond, float %val, i32 %exp0, i64 %exp1) {
315; CHECK-LABEL: define float @select_ldexp_f32_sameval_differentexp_types
316; CHECK-SAME: (i1 [[COND:%.*]], float [[VAL:%.*]], i32 [[EXP0:%.*]], i64 [[EXP1:%.*]]) {
317; CHECK-NEXT:    [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[VAL]], i32 [[EXP0]])
318; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i64(float [[VAL]], i64 [[EXP1]])
319; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], float [[LDEXP0]], float [[LDEXP1]]
320; CHECK-NEXT:    ret float [[SELECT]]
321;
322  %ldexp0 = call float @llvm.ldexp.f32.i32(float %val, i32 %exp0)
323  %ldexp1 = call float @llvm.ldexp.f32.i64(float %val, i64 %exp1)
324  %select = select i1 %cond, float %ldexp0, float %ldexp1
325  ret float %select
326}
327
328;---------------------------------------------------------------------
329; ldexp(ldexp(x, a), b) -> ldexp(x, a + b)
330;---------------------------------------------------------------------
331
332define float @ldexp_ldexp(float %x, i32 %a, i32 %b) {
333; CHECK-LABEL: define float @ldexp_ldexp
334; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
335; CHECK-NEXT:    [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]])
336; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]])
337; CHECK-NEXT:    ret float [[LDEXP1]]
338;
339  %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a)
340  %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b)
341  ret float %ldexp1
342}
343
344define float @ldexp_reassoc_ldexp(float %x, i32 %a, i32 %b) {
345; CHECK-LABEL: define float @ldexp_reassoc_ldexp
346; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
347; CHECK-NEXT:    [[LDEXP0:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]])
348; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]])
349; CHECK-NEXT:    ret float [[LDEXP1]]
350;
351  %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 %a)
352  %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b)
353  ret float %ldexp1
354}
355
356define float @ldexp_ldexp_reassoc(float %x, i32 %a, i32 %b) {
357; CHECK-LABEL: define float @ldexp_ldexp_reassoc
358; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
359; CHECK-NEXT:    [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]])
360; CHECK-NEXT:    [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]])
361; CHECK-NEXT:    ret float [[LDEXP1]]
362;
363  %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a)
364  %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b)
365  ret float %ldexp1
366}
367
368define float @ldexp_reassoc_ldexp_reassoc(float %x, i32 %a, i32 %b) {
369; CHECK-LABEL: define float @ldexp_reassoc_ldexp_reassoc
370; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
371; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A]], [[B]]
372; CHECK-NEXT:    [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[X]], i32 [[TMP1]])
373; CHECK-NEXT:    ret float [[LDEXP1]]
374;
375  %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 %a)
376  %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b)
377  ret float %ldexp1
378}
379
380define float @ldexp_reassoc_nsz_ldexp_reassoc_nsz(float %x, i32 %a, i32 %b) {
381; CHECK-LABEL: define float @ldexp_reassoc_nsz_ldexp_reassoc_nsz
382; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
383; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A]], [[B]]
384; CHECK-NEXT:    [[LDEXP1:%.*]] = call reassoc nsz float @llvm.ldexp.f32.i32(float [[X]], i32 [[TMP1]])
385; CHECK-NEXT:    ret float [[LDEXP1]]
386;
387  %ldexp0 = call reassoc nsz float @llvm.ldexp.f32.i32(float %x, i32 %a)
388  %ldexp1 = call reassoc nsz float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b)
389  ret float %ldexp1
390}
391
392; Test that we or the inner and outer flags
393define float @ldexp_reassoc_ldexp_reassoc_preserve_flags(float %x, i32 %a, i32 %b) {
394; CHECK-LABEL: define float @ldexp_reassoc_ldexp_reassoc_preserve_flags
395; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
396; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A]], [[B]]
397; CHECK-NEXT:    [[LDEXP1:%.*]] = call reassoc nnan ninf float @llvm.ldexp.f32.i32(float [[X]], i32 [[TMP1]])
398; CHECK-NEXT:    ret float [[LDEXP1]]
399;
400  %ldexp0 = call reassoc ninf float @llvm.ldexp.f32.i32(float %x, i32 %a)
401  %ldexp1 = call reassoc nnan float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b)
402  ret float %ldexp1
403}
404
405define <2 x float> @ldexp_reassoc_ldexp_reassoc_vec(<2 x float> %x, <2 x i32> %a, <2 x i32> %b) {
406; CHECK-LABEL: define <2 x float> @ldexp_reassoc_ldexp_reassoc_vec
407; CHECK-SAME: (<2 x float> [[X:%.*]], <2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]]) {
408; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[A]], [[B]]
409; CHECK-NEXT:    [[LDEXP1:%.*]] = call reassoc <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> [[TMP1]])
410; CHECK-NEXT:    ret <2 x float> [[LDEXP1]]
411;
412  %ldexp0 = call reassoc <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> %a)
413  %ldexp1 = call reassoc <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %ldexp0, <2 x i32> %b)
414  ret <2 x float> %ldexp1
415}
416
417define float @ldexp_multi_use_ldexp(float %x, i32 %a, i32 %b, ptr %ptr) {
418; CHECK-LABEL: define float @ldexp_multi_use_ldexp
419; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]], ptr [[PTR:%.*]]) {
420; CHECK-NEXT:    [[LDEXP0:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]])
421; CHECK-NEXT:    store float [[LDEXP0]], ptr [[PTR]], align 4
422; CHECK-NEXT:    [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]])
423; CHECK-NEXT:    ret float [[LDEXP1]]
424;
425  %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 %a)
426  store float %ldexp0, ptr %ptr
427  %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b)
428  ret float %ldexp1
429}
430
431; Test edge case where the intrinsic is declared with different int types.
432define float @ldexp_ldexp_different_exp_type(float %x, i32 %a, i64 %b) {
433; CHECK-LABEL: define float @ldexp_ldexp_different_exp_type
434; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i64 [[B:%.*]]) {
435; CHECK-NEXT:    [[LDEXP0:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]])
436; CHECK-NEXT:    [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i64(float [[LDEXP0]], i64 [[B]])
437; CHECK-NEXT:    ret float [[LDEXP1]]
438;
439  %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 %a)
440  %ldexp1 = call reassoc float @llvm.ldexp.f32.i64(float %ldexp0, i64 %b)
441  ret float %ldexp1
442}
443
444define float @ldexp_ldexp_constants(float %x) {
445; CHECK-LABEL: define float @ldexp_ldexp_constants
446; CHECK-SAME: (float [[X:%.*]]) {
447; CHECK-NEXT:    [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[X]], i32 32)
448; CHECK-NEXT:    ret float [[LDEXP1]]
449;
450  %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 8)
451  %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 24)
452  ret float %ldexp1
453}
454
455define float @ldexp_ldexp_constants_nsz(float %x) {
456; CHECK-LABEL: define float @ldexp_ldexp_constants_nsz
457; CHECK-SAME: (float [[X:%.*]]) {
458; CHECK-NEXT:    [[LDEXP1:%.*]] = call reassoc nsz float @llvm.ldexp.f32.i32(float [[X]], i32 32)
459; CHECK-NEXT:    ret float [[LDEXP1]]
460;
461  %ldexp0 = call reassoc nsz float @llvm.ldexp.f32.i32(float %x, i32 8)
462  %ldexp1 = call reassoc nsz float @llvm.ldexp.f32.i32(float %ldexp0, i32 24)
463  ret float %ldexp1
464}
465
466define float @ldexp_ldexp_constants_nsz0(float %x) {
467; CHECK-LABEL: define float @ldexp_ldexp_constants_nsz0
468; CHECK-SAME: (float [[X:%.*]]) {
469; CHECK-NEXT:    [[LDEXP1:%.*]] = call reassoc nsz float @llvm.ldexp.f32.i32(float [[X]], i32 32)
470; CHECK-NEXT:    ret float [[LDEXP1]]
471;
472  %ldexp0 = call reassoc nsz float @llvm.ldexp.f32.i32(float %x, i32 8)
473  %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 24)
474  ret float %ldexp1
475}
476
477define float @ldexp_ldexp_constants_nsz1(float %x) {
478; CHECK-LABEL: define float @ldexp_ldexp_constants_nsz1
479; CHECK-SAME: (float [[X:%.*]]) {
480; CHECK-NEXT:    [[LDEXP1:%.*]] = call reassoc nsz float @llvm.ldexp.f32.i32(float [[X]], i32 32)
481; CHECK-NEXT:    ret float [[LDEXP1]]
482;
483  %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 8)
484  %ldexp1 = call reassoc nsz float @llvm.ldexp.f32.i32(float %ldexp0, i32 24)
485  ret float %ldexp1
486}
487
488define float @ldexp_ldexp_opposite_constants(float %x) {
489; CHECK-LABEL: define float @ldexp_ldexp_opposite_constants
490; CHECK-SAME: (float [[X:%.*]]) {
491; CHECK-NEXT:    ret float [[X]]
492;
493  %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 8)
494  %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 -8)
495  ret float %ldexp1
496}
497
498define float @ldexp_ldexp_negated_variable_reassoc(float %x, i32 %a) {
499; CHECK-LABEL: define float @ldexp_ldexp_negated_variable_reassoc
500; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]]) {
501; CHECK-NEXT:    ret float [[X]]
502;
503  %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 %a)
504  %neg.a = sub i32 0, %a
505  %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 %neg.a)
506  ret float %ldexp1
507}
508
509define float @ldexp_ldexp_negated_variable(float %x, i32 %a) {
510; CHECK-LABEL: define float @ldexp_ldexp_negated_variable
511; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]]) {
512; CHECK-NEXT:    [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]])
513; CHECK-NEXT:    [[NEG_A:%.*]] = sub i32 0, [[A]]
514; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[NEG_A]])
515; CHECK-NEXT:    ret float [[LDEXP1]]
516;
517  %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a)
518  %neg.a = sub i32 0, %a
519  %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %neg.a)
520  ret float %ldexp1
521}
522
523define float @ldexp_ldexp_first_exp_known_positive(float %x, i32 %a.arg, i32 %b) {
524; CHECK-LABEL: define float @ldexp_ldexp_first_exp_known_positive
525; CHECK-SAME: (float [[X:%.*]], i32 [[A_ARG:%.*]], i32 [[B:%.*]]) {
526; CHECK-NEXT:    [[A:%.*]] = and i32 [[A_ARG]], 127
527; CHECK-NEXT:    [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]])
528; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]])
529; CHECK-NEXT:    ret float [[LDEXP1]]
530;
531  %a = and i32 %a.arg, 127
532  %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a)
533  %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b)
534  ret float %ldexp1
535}
536
537define float @ldexp_ldexp_first_second_known_positive(float %x, i32 %a, i32 %b.arg) {
538; CHECK-LABEL: define float @ldexp_ldexp_first_second_known_positive
539; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B_ARG:%.*]]) {
540; CHECK-NEXT:    [[B:%.*]] = and i32 [[B_ARG]], 127
541; CHECK-NEXT:    [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]])
542; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]])
543; CHECK-NEXT:    ret float [[LDEXP1]]
544;
545  %b = and i32 %b.arg, 127
546  %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a)
547  %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b)
548  ret float %ldexp1
549}
550
551define float @ldexp_ldexp_both_exp_known_positive(float %x, i32 %a.arg, i32 %b.arg) {
552; CHECK-LABEL: define float @ldexp_ldexp_both_exp_known_positive
553; CHECK-SAME: (float [[X:%.*]], i32 [[A_ARG:%.*]], i32 [[B_ARG:%.*]]) {
554; CHECK-NEXT:    [[A:%.*]] = and i32 [[A_ARG]], 127
555; CHECK-NEXT:    [[B:%.*]] = and i32 [[B_ARG]], 127
556; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i32 [[A]], [[B]]
557; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[TMP1]])
558; CHECK-NEXT:    ret float [[LDEXP1]]
559;
560  %a = and i32 %a.arg, 127
561  %b = and i32 %b.arg, 127
562  %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a)
563  %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b)
564  ret float %ldexp1
565}
566
567define float @ldexp_ldexp_both_exp_known_negative(float %x, ptr %a.ptr, ptr %b.ptr) {
568; CHECK-LABEL: define float @ldexp_ldexp_both_exp_known_negative
569; CHECK-SAME: (float [[X:%.*]], ptr [[A_PTR:%.*]], ptr [[B_PTR:%.*]]) {
570; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[A_PTR]], align 4, !range [[RNG0:![0-9]+]]
571; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[B_PTR]], align 4, !range [[RNG0]]
572; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[A]], [[B]]
573; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[TMP1]])
574; CHECK-NEXT:    ret float [[LDEXP1]]
575;
576  %a = load i32, ptr %a.ptr, !range !0
577  %b = load i32, ptr %b.ptr, !range !0
578  %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a)
579  %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b)
580  ret float %ldexp1
581}
582
583define float @ldexp_ldexp_exp_known_negative_and_positive(float %x, ptr %a.ptr, ptr %b.ptr) {
584; CHECK-LABEL: define float @ldexp_ldexp_exp_known_negative_and_positive
585; CHECK-SAME: (float [[X:%.*]], ptr [[A_PTR:%.*]], ptr [[B_PTR:%.*]]) {
586; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[A_PTR]], align 4, !range [[RNG0]]
587; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[B_PTR]], align 4, !range [[RNG1:![0-9]+]]
588; CHECK-NEXT:    [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]])
589; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]])
590; CHECK-NEXT:    ret float [[LDEXP1]]
591;
592  %a = load i32, ptr %a.ptr, !range !0
593  %b = load i32, ptr %b.ptr, !range !1
594  %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a)
595  %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b)
596  ret float %ldexp1
597}
598
599define float @ldexp_ldexp_exp_known_positive_and_negative(float %x, ptr %a.ptr, ptr %b.ptr) {
600; CHECK-LABEL: define float @ldexp_ldexp_exp_known_positive_and_negative
601; CHECK-SAME: (float [[X:%.*]], ptr [[A_PTR:%.*]], ptr [[B_PTR:%.*]]) {
602; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[A_PTR]], align 4, !range [[RNG1]]
603; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[B_PTR]], align 4, !range [[RNG0]]
604; CHECK-NEXT:    [[LDEXP0:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[A]])
605; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[LDEXP0]], i32 [[B]])
606; CHECK-NEXT:    ret float [[LDEXP1]]
607;
608  %a = load i32, ptr %a.ptr, !range !1
609  %b = load i32, ptr %b.ptr, !range !0
610  %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a)
611  %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b)
612  ret float %ldexp1
613}
614
615define float @ldexp_reassoc_ldexp_reassoc_0(float %x, i32 %y) {
616; CHECK-LABEL: define float @ldexp_reassoc_ldexp_reassoc_0
617; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
618; CHECK-NEXT:    [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]])
619; CHECK-NEXT:    ret float [[LDEXP1]]
620;
621  %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 0)
622  %ldexp1 = call reassoc float @llvm.ldexp.f32.i32(float %ldexp0, i32 %y)
623  ret float %ldexp1
624}
625
626define float @ldexp_ldexp_0(float %x, i32 %y) {
627; CHECK-LABEL: define float @ldexp_ldexp_0
628; CHECK-SAME: (float [[X:%.*]], i32 [[Y:%.*]]) {
629; CHECK-NEXT:    [[LDEXP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]])
630; CHECK-NEXT:    ret float [[LDEXP1]]
631;
632  %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 0)
633  %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %y)
634  ret float %ldexp1
635}
636
637;---------------------------------------------------------------------
638; ldexp(x, k) -> fmul x, 2**k
639;---------------------------------------------------------------------
640
641define float @ldexp_neg150(float %x) {
642; CHECK-LABEL: define float @ldexp_neg150
643; CHECK-SAME: (float [[X:%.*]]) {
644; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -150)
645; CHECK-NEXT:    ret float [[LDEXP]]
646;
647  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -150)
648  ret float %ldexp
649}
650
651define float @ldexp_neg149(float %x) {
652; CHECK-LABEL: define float @ldexp_neg149
653; CHECK-SAME: (float [[X:%.*]]) {
654; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -149)
655; CHECK-NEXT:    ret float [[LDEXP]]
656;
657  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -149)
658  ret float %ldexp
659}
660
661define float @ldexp_neg148(float %x) {
662; CHECK-LABEL: define float @ldexp_neg148
663; CHECK-SAME: (float [[X:%.*]]) {
664; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -148)
665; CHECK-NEXT:    ret float [[LDEXP]]
666;
667  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -148)
668  ret float %ldexp
669}
670
671define float @ldexp_neg127(float %x) {
672; CHECK-LABEL: define float @ldexp_neg127
673; CHECK-SAME: (float [[X:%.*]]) {
674; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -127)
675; CHECK-NEXT:    ret float [[LDEXP]]
676;
677  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -127)
678  ret float %ldexp
679}
680
681define float @ldexp_neg126(float %x) {
682; CHECK-LABEL: define float @ldexp_neg126
683; CHECK-SAME: (float [[X:%.*]]) {
684; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -126)
685; CHECK-NEXT:    ret float [[LDEXP]]
686;
687  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -126)
688  ret float %ldexp
689}
690
691define float @ldexp_neg125(float %x) {
692; CHECK-LABEL: define float @ldexp_neg125
693; CHECK-SAME: (float [[X:%.*]]) {
694; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -125)
695; CHECK-NEXT:    ret float [[LDEXP]]
696;
697  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -125)
698  ret float %ldexp
699}
700
701define float @ldexp_neg16(float %x) {
702; CHECK-LABEL: define float @ldexp_neg16
703; CHECK-SAME: (float [[X:%.*]]) {
704; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -16)
705; CHECK-NEXT:    ret float [[LDEXP]]
706;
707  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -16)
708  ret float %ldexp
709}
710
711define float @ldexp_neg8(float %x) {
712; CHECK-LABEL: define float @ldexp_neg8
713; CHECK-SAME: (float [[X:%.*]]) {
714; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -8)
715; CHECK-NEXT:    ret float [[LDEXP]]
716;
717  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -8)
718  ret float %ldexp
719}
720
721define float @ldexp_neg4(float %x) {
722; CHECK-LABEL: define float @ldexp_neg4
723; CHECK-SAME: (float [[X:%.*]]) {
724; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -4)
725; CHECK-NEXT:    ret float [[LDEXP]]
726;
727  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -4)
728  ret float %ldexp
729}
730
731define float @ldexp_neg2(float %x) {
732; CHECK-LABEL: define float @ldexp_neg2
733; CHECK-SAME: (float [[X:%.*]]) {
734; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -2)
735; CHECK-NEXT:    ret float [[LDEXP]]
736;
737  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -2)
738  ret float %ldexp
739}
740
741define float @ldexp_neg1(float %x) {
742; CHECK-LABEL: define float @ldexp_neg1
743; CHECK-SAME: (float [[X:%.*]]) {
744; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -1)
745; CHECK-NEXT:    ret float [[LDEXP]]
746;
747  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -1)
748  ret float %ldexp
749}
750
751define float @ldexp_0(float %x) {
752; CHECK-LABEL: define float @ldexp_0
753; CHECK-SAME: (float [[X:%.*]]) {
754; CHECK-NEXT:    ret float [[X]]
755;
756  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 0)
757  ret float %ldexp
758}
759
760define float @ldexp_1(float %x) {
761; CHECK-LABEL: define float @ldexp_1
762; CHECK-SAME: (float [[X:%.*]]) {
763; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 1)
764; CHECK-NEXT:    ret float [[LDEXP]]
765;
766  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 1)
767  ret float %ldexp
768}
769
770define float @ldexp_2(float %x) {
771; CHECK-LABEL: define float @ldexp_2
772; CHECK-SAME: (float [[X:%.*]]) {
773; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 2)
774; CHECK-NEXT:    ret float [[LDEXP]]
775;
776  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 2)
777  ret float %ldexp
778}
779
780define float @ldexp_3(float %x) {
781; CHECK-LABEL: define float @ldexp_3
782; CHECK-SAME: (float [[X:%.*]]) {
783; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 3)
784; CHECK-NEXT:    ret float [[LDEXP]]
785;
786  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 3)
787  ret float %ldexp
788}
789
790define float @ldexp_10(float %x) {
791; CHECK-LABEL: define float @ldexp_10
792; CHECK-SAME: (float [[X:%.*]]) {
793; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 10)
794; CHECK-NEXT:    ret float [[LDEXP]]
795;
796  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 10)
797  ret float %ldexp
798}
799
800define float @ldexp_125(float %x) {
801; CHECK-LABEL: define float @ldexp_125
802; CHECK-SAME: (float [[X:%.*]]) {
803; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 125)
804; CHECK-NEXT:    ret float [[LDEXP]]
805;
806  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 125)
807  ret float %ldexp
808}
809
810define float @ldexp_126(float %x) {
811; CHECK-LABEL: define float @ldexp_126
812; CHECK-SAME: (float [[X:%.*]]) {
813; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 126)
814; CHECK-NEXT:    ret float [[LDEXP]]
815;
816  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 126)
817  ret float %ldexp
818}
819
820define float @ldexp_127(float %x) {
821; CHECK-LABEL: define float @ldexp_127
822; CHECK-SAME: (float [[X:%.*]]) {
823; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 127)
824; CHECK-NEXT:    ret float [[LDEXP]]
825;
826  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 127)
827  ret float %ldexp
828}
829
830define <2 x float> @ldexp_3_vector(<2 x float> %x) {
831; CHECK-LABEL: define <2 x float> @ldexp_3_vector
832; CHECK-SAME: (<2 x float> [[X:%.*]]) {
833; CHECK-NEXT:    [[LDEXP:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> splat (i32 3))
834; CHECK-NEXT:    ret <2 x float> [[LDEXP]]
835;
836  %ldexp = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> <i32 3, i32 3>)
837  ret <2 x float> %ldexp
838}
839
840define <2 x float> @ldexp_3_undef_vector(<2 x float> %x) {
841; CHECK-LABEL: define <2 x float> @ldexp_3_undef_vector
842; CHECK-SAME: (<2 x float> [[X:%.*]]) {
843; CHECK-NEXT:    [[LDEXP:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> <i32 3, i32 poison>)
844; CHECK-NEXT:    ret <2 x float> [[LDEXP]]
845;
846  %ldexp = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> <i32 3, i32 poison>)
847  ret <2 x float> %ldexp
848}
849
850define <2 x float> @ldexp_3_4_vector(<2 x float> %x) {
851; CHECK-LABEL: define <2 x float> @ldexp_3_4_vector
852; CHECK-SAME: (<2 x float> [[X:%.*]]) {
853; CHECK-NEXT:    [[LDEXP:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> <i32 3, i32 4>)
854; CHECK-NEXT:    ret <2 x float> [[LDEXP]]
855;
856  %ldexp = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> <i32 3, i32 4>)
857  ret <2 x float> %ldexp
858}
859
860define float @ldexp_2_flags(float %x) {
861; CHECK-LABEL: define float @ldexp_2_flags
862; CHECK-SAME: (float [[X:%.*]]) {
863; CHECK-NEXT:    [[LDEXP:%.*]] = call nsz contract float @llvm.ldexp.f32.i32(float [[X]], i32 2)
864; CHECK-NEXT:    ret float [[LDEXP]]
865;
866  %ldexp = call contract nsz float @llvm.ldexp.f32.i32(float %x, i32 2)
867  ret float %ldexp
868}
869
870define float @ldexp_metadata(float %x) {
871; CHECK-LABEL: define float @ldexp_metadata
872; CHECK-SAME: (float [[X:%.*]]) {
873; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 2), !foo [[META2:![0-9]+]]
874; CHECK-NEXT:    ret float [[LDEXP]]
875;
876  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 2), !foo !2
877  ret float %ldexp
878}
879
880define float @ldexp_8_contractable(float %x, float %y) {
881; CHECK-LABEL: define float @ldexp_8_contractable
882; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
883; CHECK-NEXT:    [[LDEXP:%.*]] = call contract float @llvm.ldexp.f32.i32(float [[X]], i32 2)
884; CHECK-NEXT:    [[FADD:%.*]] = fadd contract float [[LDEXP]], [[Y]]
885; CHECK-NEXT:    ret float [[FADD]]
886;
887  %ldexp = call contract float @llvm.ldexp.f32.i32(float %x, i32 2)
888  %fadd = fadd contract float %ldexp, %y
889  ret float %fadd
890}
891
892define float @ldexp_f32_mask_select_0(i1 %cond, float %x, i32 %y) {
893; CHECK-LABEL: define float @ldexp_f32_mask_select_0
894; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) {
895; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]])
896; CHECK-NEXT:    [[LDEXP:%.*]] = select i1 [[COND]], float [[TMP1]], float [[X]]
897; CHECK-NEXT:    ret float [[LDEXP]]
898;
899  %select = select i1 %cond, i32 %y, i32 0
900  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %select)
901  ret float %ldexp
902}
903
904define float @ldexp_nnan_f32_mask_select_0(i1 %cond, float %x, i32 %y) {
905; CHECK-LABEL: define float @ldexp_nnan_f32_mask_select_0
906; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) {
907; CHECK-NEXT:    [[TMP1:%.*]] = call nnan float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]])
908; CHECK-NEXT:    [[LDEXP:%.*]] = select i1 [[COND]], float [[TMP1]], float [[X]]
909; CHECK-NEXT:    ret float [[LDEXP]]
910;
911  %select = select i1 %cond, i32 %y, i32 0
912  %ldexp = call nnan float @llvm.ldexp.f32.i32(float %x, i32 %select)
913  ret float %ldexp
914}
915
916define float @ldexp_flags_f32_mask_select_0(i1 %cond, float %x, i32 %y) {
917; CHECK-LABEL: define float @ldexp_flags_f32_mask_select_0
918; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) {
919; CHECK-NEXT:    [[TMP1:%.*]] = call ninf nsz float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]])
920; CHECK-NEXT:    [[LDEXP:%.*]] = select i1 [[COND]], float [[TMP1]], float [[X]]
921; CHECK-NEXT:    ret float [[LDEXP]]
922;
923  %select = select i1 %cond, i32 %y, i32 0
924  %ldexp = call nsz ninf float @llvm.ldexp.f32.i32(float %x, i32 %select)
925  ret float %ldexp
926}
927
928define float @ldexp_f32_mask_select_0_swap(i1 %cond, float %x, i32 %y) {
929; CHECK-LABEL: define float @ldexp_f32_mask_select_0_swap
930; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) {
931; CHECK-NEXT:    [[TMP1:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[Y]])
932; CHECK-NEXT:    [[LDEXP:%.*]] = select i1 [[COND]], float [[X]], float [[TMP1]]
933; CHECK-NEXT:    ret float [[LDEXP]]
934;
935  %select = select i1 %cond, i32 0, i32 %y
936  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %select)
937  ret float %ldexp
938}
939
940define float @ldexp_f32_mask_select_1(i1 %cond, float %x, i32 %y) {
941; CHECK-LABEL: define float @ldexp_f32_mask_select_1
942; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) {
943; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 [[Y]], i32 1
944; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]])
945; CHECK-NEXT:    ret float [[LDEXP]]
946;
947  %select = select i1 %cond, i32 %y, i32 1
948  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %select)
949  ret float %ldexp
950}
951
952define float @ldexp_f32_mask_select_0_multi_use(i1 %cond, float %x, i32 %y, ptr %ptr) {
953; CHECK-LABEL: define float @ldexp_f32_mask_select_0_multi_use
954; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]], ptr [[PTR:%.*]]) {
955; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 [[Y]], i32 0
956; CHECK-NEXT:    store i32 [[SELECT]], ptr [[PTR]], align 4
957; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]])
958; CHECK-NEXT:    ret float [[LDEXP]]
959;
960  %select = select i1 %cond, i32 %y, i32 0
961  store i32 %select, ptr %ptr
962  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %select)
963  ret float %ldexp
964}
965
966define float @ldexp_f32_mask_select_0_swap_multi_use(i1 %cond, float %x, i32 %y, ptr %ptr) {
967; CHECK-LABEL: define float @ldexp_f32_mask_select_0_swap_multi_use
968; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]], ptr [[PTR:%.*]]) {
969; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 0, i32 [[Y]]
970; CHECK-NEXT:    store i32 [[SELECT]], ptr [[PTR]], align 4
971; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 [[SELECT]])
972; CHECK-NEXT:    ret float [[LDEXP]]
973;
974  %select = select i1 %cond, i32 0, i32 %y
975  store i32 %select, ptr %ptr
976  %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 %select)
977  ret float %ldexp
978}
979
980define float @ldexp_f32_mask_select_0_strictfp(i1 %cond, float %x, i32 %y) #0 {
981; CHECK-LABEL: define float @ldexp_f32_mask_select_0_strictfp
982; CHECK-SAME: (i1 [[COND:%.*]], float [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR1:[0-9]+]] {
983; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], i32 [[Y]], i32 0
984; CHECK-NEXT:    [[LDEXP:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float [[X]], i32 [[SELECT]], metadata !"round.dynamic", metadata !"fpexcept.strict")
985; CHECK-NEXT:    ret float [[LDEXP]]
986;
987  %select = select i1 %cond, i32 %y, i32 0
988  %ldexp = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 %select, metadata !"round.dynamic", metadata !"fpexcept.strict")
989  ret float %ldexp
990}
991
992define <2 x float> @ldexp_v2f32_mask_select_0(<2 x i1> %cond, <2 x float> %x, <2 x i32> %y) {
993; CHECK-LABEL: define <2 x float> @ldexp_v2f32_mask_select_0
994; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
995; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> [[Y]])
996; CHECK-NEXT:    [[LDEXP:%.*]] = select <2 x i1> [[COND]], <2 x float> [[TMP1]], <2 x float> [[X]]
997; CHECK-NEXT:    ret <2 x float> [[LDEXP]]
998;
999  %select = select <2 x i1> %cond, <2 x i32> %y, <2 x i32> zeroinitializer
1000  %ldexp = call nsz nnan <2 x float> @llvm.ldexp.f32.v2i32(<2 x float> %x, <2 x i32> %select)
1001  ret <2 x float> %ldexp
1002}
1003
1004define <2 x float> @ldexp_v2f32_mask_select_0_swap(<2 x i1> %cond, <2 x float> %x, <2 x i32> %y) {
1005; CHECK-LABEL: define <2 x float> @ldexp_v2f32_mask_select_0_swap
1006; CHECK-SAME: (<2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) {
1007; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> [[Y]])
1008; CHECK-NEXT:    [[LDEXP:%.*]] = select <2 x i1> [[COND]], <2 x float> [[X]], <2 x float> [[TMP1]]
1009; CHECK-NEXT:    ret <2 x float> [[LDEXP]]
1010;
1011  %select = select <2 x i1> %cond, <2 x i32> zeroinitializer, <2 x i32> %y
1012  %ldexp = call nsz nnan <2 x float> @llvm.ldexp.f32.v2i32(<2 x float> %x, <2 x i32> %select)
1013  ret <2 x float> %ldexp
1014}
1015
1016attributes #0 = { strictfp }
1017
1018!0 = !{i32 -127, i32 0}
1019!1 = !{i32 0, i32 127}
1020!2 = !{}
1021