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
4 declare float @llvm.ldexp.f32.i32(float, i32)
5 declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float>, <2 x i32>)
6 declare float @llvm.ldexp.f32.i64(float, i64)
8 ; select c, (ldexp val, e0), (ldexp val, e1) -> ldexp val, (select c, e0, e1)
9 define 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]]
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
22 define 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]]
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
35 define 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]]
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
48 define 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]]
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
61 define 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]]
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
77 define 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]]
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
93 define 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]]
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
111 ; select c, (ldexp val0, e), (ldexp val1, ee) -> ldexp (select c, val0, val1), e
112 define 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]]
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
125 define 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]]
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
138 define 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]]
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
151 define 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]]
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
164 define 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]]
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
180 define 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]]
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
196 define 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]]
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
210 define 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]]
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
227 define 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]]
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
244 define 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]]
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
262 define <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]]
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
275 define <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]]
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
288 define <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]]
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
302 define 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]]
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
314 define 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]]
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
328 ;---------------------------------------------------------------------
329 ; ldexp(ldexp(x, a), b) -> ldexp(x, a + b)
330 ;---------------------------------------------------------------------
332 define 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]]
339 %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 %a)
340 %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %b)
344 define 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]]
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)
356 define 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]]
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)
368 define 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]]
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)
380 define 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]]
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)
392 ; Test that we or the inner and outer flags
393 define 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]]
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)
405 define <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]]
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
417 define 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]]
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)
431 ; Test edge case where the intrinsic is declared with different int types.
432 define 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]]
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)
444 define 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]]
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)
455 define 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]]
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)
466 define 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]]
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)
477 define 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]]
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)
488 define 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]]
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)
498 define 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]]
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)
509 define 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]]
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)
523 define 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]]
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)
537 define 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]]
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)
551 define 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]]
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)
567 define 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]]
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)
583 define 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]]
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)
599 define 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]]
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)
615 define 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]]
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)
626 define 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]]
632 %ldexp0 = call float @llvm.ldexp.f32.i32(float %x, i32 0)
633 %ldexp1 = call float @llvm.ldexp.f32.i32(float %ldexp0, i32 %y)
637 ;---------------------------------------------------------------------
638 ; ldexp(x, k) -> fmul x, 2**k
639 ;---------------------------------------------------------------------
641 define 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]]
647 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -150)
651 define 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]]
657 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -149)
661 define 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]]
667 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -148)
671 define 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]]
677 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -127)
681 define 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]]
687 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -126)
691 define 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]]
697 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -125)
701 define 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]]
707 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -16)
711 define 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]]
717 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -8)
721 define 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]]
727 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -4)
731 define 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]]
737 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -2)
741 define 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]]
747 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -1)
751 define float @ldexp_0(float %x) {
752 ; CHECK-LABEL: define float @ldexp_0
753 ; CHECK-SAME: (float [[X:%.*]]) {
754 ; CHECK-NEXT: ret float [[X]]
756 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 0)
760 define 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]]
766 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 1)
770 define 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]]
776 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 2)
780 define 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]]
786 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 3)
790 define 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]]
796 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 10)
800 define 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]]
806 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 125)
810 define 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]]
816 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 126)
820 define 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]]
826 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 127)
830 define <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> <i32 3, i32 3>)
834 ; CHECK-NEXT: ret <2 x float> [[LDEXP]]
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
840 define <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]]
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
850 define <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]]
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
860 define 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]]
866 %ldexp = call contract nsz float @llvm.ldexp.f32.i32(float %x, i32 2)
870 define 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 !2
874 ; CHECK-NEXT: ret float [[LDEXP]]
876 %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 2), !foo !2
880 define 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]]
887 %ldexp = call contract float @llvm.ldexp.f32.i32(float %x, i32 2)
888 %fadd = fadd contract float %ldexp, %y
892 !0 = !{i32 -127, i32 0}
893 !1 = !{i32 0, i32 127}