[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Transforms / InstSimplify / ldexp.ll
blobd39f6a1e49673f28073f9534dcbd655d67bbb36d
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
4 define float @ldexp_f32_undef_undef() {
5 ; CHECK-LABEL: @ldexp_f32_undef_undef(
6 ; CHECK-NEXT:    ret float 0x7FF8000000000000
8   %call = call float @llvm.ldexp.f32.i32(float undef, i32 undef)
9   ret float %call
12 define float @ldexp_f32_poison_undef() {
13 ; CHECK-LABEL: @ldexp_f32_poison_undef(
14 ; CHECK-NEXT:    ret float poison
16   %call = call float @llvm.ldexp.f32.i32(float poison, i32 undef)
17   ret float %call
20 define float @ldexp_f32_undef_poison() {
21 ; CHECK-LABEL: @ldexp_f32_undef_poison(
22 ; CHECK-NEXT:    ret float undef
24   %call = call float @llvm.ldexp.f32.i32(float undef, i32 poison)
25   ret float %call
28 define float @ldexp_f32_poison_poison() {
29 ; CHECK-LABEL: @ldexp_f32_poison_poison(
30 ; CHECK-NEXT:    ret float poison
32   %call = call float @llvm.ldexp.f32.i32(float poison, i32 poison)
33   ret float %call
36 ; If the exponent is 0, it doesn't matter if the first argument is
37 ; constant or not.
38 define void @ldexp_f32_exp0(float %x) {
39 ; CHECK-LABEL: @ldexp_f32_exp0(
40 ; CHECK-NEXT:    store volatile float [[X:%.*]], ptr addrspace(1) undef, align 4
41 ; CHECK-NEXT:    store volatile float [[X]], ptr addrspace(1) undef, align 4
42 ; CHECK-NEXT:    [[ONE:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 1)
43 ; CHECK-NEXT:    store volatile float [[ONE]], ptr addrspace(1) undef, align 4
44 ; CHECK-NEXT:    ret void
46   %zero = call float @llvm.ldexp.f32.i32(float %x, i32 0)
47   store volatile float %zero, ptr addrspace(1) undef
49   %undef = call float @llvm.ldexp.f32.i32(float %x, i32 undef)
50   store volatile float %undef, ptr addrspace(1) undef
52   %one = call float @llvm.ldexp.f32.i32(float %x, i32 1)
53   store volatile float %one, ptr addrspace(1) undef
54   ret void
57 define void @ldexp_v2f32_exp0(<2 x float> %x) {
58 ; CHECK-LABEL: @ldexp_v2f32_exp0(
59 ; CHECK-NEXT:    store volatile <2 x float> [[X:%.*]], ptr addrspace(1) undef, align 8
60 ; CHECK-NEXT:    [[PART_UNDEF1:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> <i32 undef, i32 0>)
61 ; CHECK-NEXT:    store volatile <2 x float> [[PART_UNDEF1]], ptr addrspace(1) undef, align 8
62 ; CHECK-NEXT:    store volatile <2 x float> [[X]], ptr addrspace(1) undef, align 8
63 ; CHECK-NEXT:    ret void
65   %part.undef0 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> <i32 0, i32 poison>)
66   store volatile <2 x float> %part.undef0, ptr addrspace(1) undef
68   %part.undef1 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> <i32 undef, i32 0>)
69   store volatile <2 x float> %part.undef1, ptr addrspace(1) undef
71   %zero = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> zeroinitializer)
72   store volatile <2 x float> %zero, ptr addrspace(1) undef
73   ret void
76 ; Test variable exponent but zero or undef value.
77 define void @ldexp_f32_val0(i32 %y) {
78 ; CHECK-LABEL: @ldexp_f32_val0(
79 ; CHECK-NEXT:    store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4
80 ; CHECK-NEXT:    store volatile float -0.000000e+00, ptr addrspace(1) undef, align 4
81 ; CHECK-NEXT:    store volatile float 0x7FF8000000000000, ptr addrspace(1) undef, align 4
82 ; CHECK-NEXT:    ret void
84   %zero = call float @llvm.ldexp.f32.i32(float 0.0, i32 %y)
85   store volatile float %zero, ptr addrspace(1) undef
87   %neg.zero = call float @llvm.ldexp.f32.i32(float -0.0, i32 %y)
88   store volatile float %neg.zero, ptr addrspace(1) undef
90   %undef = call float @llvm.ldexp.f32.i32(float undef, i32 %y)
91   store volatile float %undef, ptr addrspace(1) undef
92   ret void
95 define void @ldexp_f32_val_infinity(i32 %y) {
96 ; CHECK-LABEL: @ldexp_f32_val_infinity(
97 ; CHECK-NEXT:    store volatile float 0x7FF0000000000000, ptr addrspace(1) undef, align 4
98 ; CHECK-NEXT:    store volatile float 0xFFF0000000000000, ptr addrspace(1) undef, align 4
99 ; CHECK-NEXT:    store volatile float 0x7FF0000000000000, ptr addrspace(1) undef, align 4
100 ; CHECK-NEXT:    store volatile float 0xFFF0000000000000, ptr addrspace(1) undef, align 4
101 ; CHECK-NEXT:    ret void
103   %inf = call float @llvm.ldexp.f32.i32(float 0x7ff0000000000000, i32 %y)
104   store volatile float %inf, ptr addrspace(1) undef
106   %neg.inf = call float @llvm.ldexp.f32.i32(float 0xfff0000000000000, i32 %y)
107   store volatile float %neg.inf, ptr addrspace(1) undef
109   %inf.zero = call float @llvm.ldexp.f32.i32(float 0x7ff0000000000000, i32 0)
110   store volatile float %inf.zero, ptr addrspace(1) undef
112   %neg.inf.zero = call float @llvm.ldexp.f32.i32(float 0xfff0000000000000, i32 0)
113   store volatile float %neg.inf.zero, ptr addrspace(1) undef
115   ret void
118 ; Signaling nan should be quieted.
119 ; Technically this depends on the ieee_mode in the mode register.
120 define void @ldexp_f32_val_nan(i32 %y) {
121 ; CHECK-LABEL: @ldexp_f32_val_nan(
122 ; CHECK-NEXT:    store volatile float 0x7FF8001000000000, ptr addrspace(1) undef, align 4
123 ; CHECK-NEXT:    store volatile float 0xFFF8000100000000, ptr addrspace(1) undef, align 4
124 ; CHECK-NEXT:    store volatile float 0x7FF8000020000000, ptr addrspace(1) undef, align 4
125 ; CHECK-NEXT:    store volatile float 0xFFFFFFFFE0000000, ptr addrspace(1) undef, align 4
126 ; CHECK-NEXT:    ret void
128   %plus.qnan = call float @llvm.ldexp.f32.i32(float 0x7ff0001000000000, i32 %y)
129   store volatile float %plus.qnan, ptr addrspace(1) undef
131   %neg.qnan = call float @llvm.ldexp.f32.i32(float 0xfff0000100000000, i32 %y)
132   store volatile float %neg.qnan, ptr addrspace(1) undef
134   %plus.snan = call float @llvm.ldexp.f32.i32(float 0x7FF0000020000000, i32 %y)
135   store volatile float %plus.snan, ptr addrspace(1) undef
137   %neg.snan = call float @llvm.ldexp.f32.i32(float 0xFFF7FFFFE0000000, i32 %y)
138   store volatile float %neg.snan, ptr addrspace(1) undef
140   ret void
143 define void @ldexp_f32_val_nan_strictfp_maytrap(i32 %y) #0 {
144 ; CHECK-LABEL: @ldexp_f32_val_nan_strictfp_maytrap(
145 ; CHECK-NEXT:    [[PLUS_QNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0001000000000, i32 [[Y:%.*]], metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0:[0-9]+]]
146 ; CHECK-NEXT:    store volatile float [[PLUS_QNAN]], ptr addrspace(1) undef, align 4
147 ; CHECK-NEXT:    [[NEG_QNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF0000100000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]]
148 ; CHECK-NEXT:    store volatile float [[NEG_QNAN]], ptr addrspace(1) undef, align 4
149 ; CHECK-NEXT:    [[PLUS_SNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]]
150 ; CHECK-NEXT:    store volatile float [[PLUS_SNAN]], ptr addrspace(1) undef, align 4
151 ; CHECK-NEXT:    [[NEG_SNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF7FFFFE0000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]]
152 ; CHECK-NEXT:    store volatile float [[NEG_SNAN]], ptr addrspace(1) undef, align 4
153 ; CHECK-NEXT:    store volatile float 0x7FF8000000000000, ptr addrspace(1) undef, align 4
154 ; CHECK-NEXT:    ret void
156   %plus.qnan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7ff0001000000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
157   store volatile float %plus.qnan, ptr addrspace(1) undef
159   %neg.qnan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xfff0000100000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
160   store volatile float %neg.qnan, ptr addrspace(1) undef
162   %plus.snan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
163   store volatile float %plus.snan, ptr addrspace(1) undef
165   %neg.snan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF7FFFFE0000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
166   store volatile float %neg.snan, ptr addrspace(1) undef
168   %undef = call float @llvm.experimental.constrained.ldexp.f32.i32(float undef, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
169   store volatile float %undef, ptr addrspace(1) undef
171   ret void
175 define void @ldexp_f32_val_nan_strictfp_strict(i32 %y) #0 {
176 ; CHECK-LABEL: @ldexp_f32_val_nan_strictfp_strict(
177 ; CHECK-NEXT:    [[PLUS_QNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0001000000000, i32 [[Y:%.*]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]]
178 ; CHECK-NEXT:    store volatile float [[PLUS_QNAN]], ptr addrspace(1) undef, align 4
179 ; CHECK-NEXT:    [[NEG_QNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF0000100000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]]
180 ; CHECK-NEXT:    store volatile float [[NEG_QNAN]], ptr addrspace(1) undef, align 4
181 ; CHECK-NEXT:    [[PLUS_SNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]]
182 ; CHECK-NEXT:    store volatile float [[PLUS_SNAN]], ptr addrspace(1) undef, align 4
183 ; CHECK-NEXT:    [[NEG_SNAN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF7FFFFE0000000, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]]
184 ; CHECK-NEXT:    store volatile float [[NEG_SNAN]], ptr addrspace(1) undef, align 4
185 ; CHECK-NEXT:    [[UNDEF:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float undef, i32 [[Y]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]]
186 ; CHECK-NEXT:    store volatile float 0x7FF8000000000000, ptr addrspace(1) undef, align 4
187 ; CHECK-NEXT:    ret void
189   %plus.qnan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7ff0001000000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
190   store volatile float %plus.qnan, ptr addrspace(1) undef
192   %neg.qnan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xfff0000100000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
193   store volatile float %neg.qnan, ptr addrspace(1) undef
195   %plus.snan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
196   store volatile float %plus.snan, ptr addrspace(1) undef
198   %neg.snan = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0xFFF7FFFFE0000000, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
199   store volatile float %neg.snan, ptr addrspace(1) undef
201   %undef = call float @llvm.experimental.constrained.ldexp.f32.i32(float undef, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
202   store volatile float %undef, ptr addrspace(1) undef
204   ret void
207 define void @ldexp_f32_0() {
208 ; CHECK-LABEL: @ldexp_f32_0(
209 ; CHECK-NEXT:    store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4
210 ; CHECK-NEXT:    store volatile float -0.000000e+00, ptr addrspace(1) undef, align 4
211 ; CHECK-NEXT:    store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4
212 ; CHECK-NEXT:    store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4
213 ; CHECK-NEXT:    store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4
214 ; CHECK-NEXT:    store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4
215 ; CHECK-NEXT:    store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4
216 ; CHECK-NEXT:    ret void
218   %zero = call float @llvm.ldexp.f32.i32(float 0.0, i32 0)
219   store volatile float %zero, ptr addrspace(1) undef
221   %neg.zero = call float @llvm.ldexp.f32.i32(float -0.0, i32 0)
222   store volatile float %neg.zero, ptr addrspace(1) undef
224   %one = call float @llvm.ldexp.f32.i32(float 0.0, i32 1)
225   store volatile float %one, ptr addrspace(1) undef
227   %min.exp = call float @llvm.ldexp.f32.i32(float 0.0, i32 -126)
228   store volatile float %min.exp, ptr addrspace(1) undef
230   %min.exp.sub1 = call float @llvm.ldexp.f32.i32(float 0.0, i32 -127)
231   store volatile float %min.exp.sub1, ptr addrspace(1) undef
233   %max.exp = call float @llvm.ldexp.f32.i32(float 0.0, i32 127)
234   store volatile float %max.exp, ptr addrspace(1) undef
236   %max.exp.plus1 = call float @llvm.ldexp.f32.i32(float 0.0, i32 128)
237   store volatile float %max.exp.plus1, ptr addrspace(1) undef
239   ret void
242 define void @ldexp_f32_undef_strictfp(float %x, i32 %y) #0 {
243 ; CHECK-LABEL: @ldexp_f32_undef_strictfp(
244 ; CHECK-NEXT:    [[UNDEF_EXP:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float [[X:%.*]], i32 undef, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]]
245 ; CHECK-NEXT:    store volatile float [[UNDEF_EXP]], ptr addrspace(1) undef, align 4
246 ; CHECK-NEXT:    store volatile float [[X]], ptr addrspace(1) undef, align 4
247 ; CHECK-NEXT:    store volatile float 0x7FF8000000000000, ptr addrspace(1) undef, align 4
248 ; CHECK-NEXT:    store volatile float poison, ptr addrspace(1) undef, align 4
249 ; CHECK-NEXT:    store volatile float poison, ptr addrspace(1) undef, align 4
250 ; CHECK-NEXT:    store volatile float undef, ptr addrspace(1) undef, align 4
251 ; CHECK-NEXT:    ret void
253   %undef.exp = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 undef, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
254   store volatile float %undef.exp, ptr addrspace(1) undef
255   %poison.exp = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 poison, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
256   store volatile float %poison.exp, ptr addrspace(1) undef
257   %undef.val = call float @llvm.experimental.constrained.ldexp.f32.i32(float undef, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
258   store volatile float %undef.val, ptr addrspace(1) undef
259   %poison.val = call float @llvm.experimental.constrained.ldexp.f32.i32(float poison, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
260   store volatile float %poison.val, ptr addrspace(1) undef
261   %poison.undef = call float @llvm.experimental.constrained.ldexp.f32.i32(float poison, i32 undef, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
262   store volatile float %poison.undef, ptr addrspace(1) undef
263   %undef.poison = call float @llvm.experimental.constrained.ldexp.f32.i32(float undef, i32 poison, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
264   store volatile float %undef.poison, ptr addrspace(1) undef
265   ret void
268 ; Should be able to ignore strictfp in this case
269 define void @ldexp_f32_0_strictfp(float %x) #0 {
270 ; CHECK-LABEL: @ldexp_f32_0_strictfp(
271 ; CHECK-NEXT:    store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4
272 ; CHECK-NEXT:    store volatile float -0.000000e+00, ptr addrspace(1) undef, align 4
273 ; CHECK-NEXT:    store volatile float 0.000000e+00, ptr addrspace(1) undef, align 4
274 ; CHECK-NEXT:    [[UNKNOWN_ZERO:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float [[X:%.*]], i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]]
275 ; CHECK-NEXT:    store volatile float [[UNKNOWN_ZERO]], ptr addrspace(1) undef, align 4
276 ; CHECK-NEXT:    [[UNKNOWN_UNDEF:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float [[X]], i32 undef, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]]
277 ; CHECK-NEXT:    store volatile float [[UNKNOWN_UNDEF]], ptr addrspace(1) undef, align 4
278 ; CHECK-NEXT:    [[DENORMAL_0:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]]
279 ; CHECK-NEXT:    store volatile float [[DENORMAL_0]], ptr addrspace(1) undef, align 4
280 ; CHECK-NEXT:    [[DENORMAL_1:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 1, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #[[ATTR0]]
281 ; CHECK-NEXT:    store volatile float [[DENORMAL_1]], ptr addrspace(1) undef, align 4
282 ; CHECK-NEXT:    ret void
284   %zero = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0.0, i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
285   store volatile float %zero, ptr addrspace(1) undef
287   %neg.zero = call float @llvm.experimental.constrained.ldexp.f32.i32(float -0.0, i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
288   store volatile float %neg.zero, ptr addrspace(1) undef
290   %one = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0.0, i32 1, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
291   store volatile float %one, ptr addrspace(1) undef
293   %unknown.zero = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
294   store volatile float %unknown.zero, ptr addrspace(1) undef
296   %unknown.undef = call float @llvm.experimental.constrained.ldexp.f32.i32(float %x, i32 undef, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
297   store volatile float %unknown.undef, ptr addrspace(1) undef
299   %denormal.0 = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 0, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
300   store volatile float %denormal.0, ptr addrspace(1) undef
302   %denormal.1 = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 1, metadata !"round.dynamic", metadata !"fpexcept.maytrap") #0
303   store volatile float %denormal.1, ptr addrspace(1) undef
305   ret void
308 define void @ldexp_f32() {
309 ; CHECK-LABEL: @ldexp_f32(
310 ; CHECK-NEXT:    store volatile float 2.000000e+00, ptr addrspace(1) undef, align 4
311 ; CHECK-NEXT:    store volatile float 4.000000e+00, ptr addrspace(1) undef, align 4
312 ; CHECK-NEXT:    store volatile float 8.000000e+00, ptr addrspace(1) undef, align 4
313 ; CHECK-NEXT:    store volatile float 5.000000e-01, ptr addrspace(1) undef, align 4
314 ; CHECK-NEXT:    store volatile float 0x3810000000000000, ptr addrspace(1) undef, align 4
315 ; CHECK-NEXT:    store volatile float 0x3800000000000000, ptr addrspace(1) undef, align 4
316 ; CHECK-NEXT:    store volatile float 0x47E0000000000000, ptr addrspace(1) undef, align 4
317 ; CHECK-NEXT:    store volatile float 0x7FF0000000000000, ptr addrspace(1) undef, align 4
318 ; CHECK-NEXT:    store volatile float -2.000000e+00, ptr addrspace(1) undef, align 4
319 ; CHECK-NEXT:    store volatile float -4.000000e+00, ptr addrspace(1) undef, align 4
320 ; CHECK-NEXT:    store volatile float -8.000000e+00, ptr addrspace(1) undef, align 4
321 ; CHECK-NEXT:    store volatile float -5.000000e-01, ptr addrspace(1) undef, align 4
322 ; CHECK-NEXT:    store volatile float 0xB810000000000000, ptr addrspace(1) undef, align 4
323 ; CHECK-NEXT:    store volatile float 0xB800000000000000, ptr addrspace(1) undef, align 4
324 ; CHECK-NEXT:    store volatile float 0xC7E0000000000000, ptr addrspace(1) undef, align 4
325 ; CHECK-NEXT:    store volatile float 0xFFF0000000000000, ptr addrspace(1) undef, align 4
326 ; CHECK-NEXT:    store volatile float 0x44D5000000000000, ptr addrspace(1) undef, align 4
327 ; CHECK-NEXT:    ret void
329   %one.one = call float @llvm.ldexp.f32.i32(float 1.0, i32 1)
330   store volatile float %one.one, ptr addrspace(1) undef
332   %one.two = call float @llvm.ldexp.f32.i32(float 1.0, i32 2)
333   store volatile float %one.two, ptr addrspace(1) undef
335   %one.three = call float @llvm.ldexp.f32.i32(float 1.0, i32 3)
336   store volatile float %one.three, ptr addrspace(1) undef
338   %one.negone = call float @llvm.ldexp.f32.i32(float 1.0, i32 -1)
339   store volatile float %one.negone, ptr addrspace(1) undef
341   %one.min.exp = call float @llvm.ldexp.f32.i32(float 1.0, i32 -126)
342   store volatile float %one.min.exp, ptr addrspace(1) undef
344   %one.min.exp.sub1 = call float @llvm.ldexp.f32.i32(float 1.0, i32 -127)
345   store volatile float %one.min.exp.sub1, ptr addrspace(1) undef
347   %one.max.exp = call float @llvm.ldexp.f32.i32(float 1.0, i32 127)
348   store volatile float %one.max.exp, ptr addrspace(1) undef
350   %one.max.exp.plus1 = call float @llvm.ldexp.f32.i32(float 1.0, i32 128)
351   store volatile float %one.max.exp.plus1, ptr addrspace(1) undef
353   %neg.one.one = call float @llvm.ldexp.f32.i32(float -1.0, i32 1)
354   store volatile float %neg.one.one, ptr addrspace(1) undef
356   %neg.one.two = call float @llvm.ldexp.f32.i32(float -1.0, i32 2)
357   store volatile float %neg.one.two, ptr addrspace(1) undef
359   %neg.one.three = call float @llvm.ldexp.f32.i32(float -1.0, i32 3)
360   store volatile float %neg.one.three, ptr addrspace(1) undef
362   %neg.one.negone = call float @llvm.ldexp.f32.i32(float -1.0, i32 -1)
363   store volatile float %neg.one.negone, ptr addrspace(1) undef
365   %neg.one.min.exp = call float @llvm.ldexp.f32.i32(float -1.0, i32 -126)
366   store volatile float %neg.one.min.exp, ptr addrspace(1) undef
368   %neg.one.min.exp.sub1 = call float @llvm.ldexp.f32.i32(float -1.0, i32 -127)
369   store volatile float %neg.one.min.exp.sub1, ptr addrspace(1) undef
371   %neg.one.max.exp = call float @llvm.ldexp.f32.i32(float -1.0, i32 127)
372   store volatile float %neg.one.max.exp, ptr addrspace(1) undef
374   %neg.one.max.exp.plus1 = call float @llvm.ldexp.f32.i32(float -1.0, i32 128)
375   store volatile float %neg.one.max.exp.plus1, ptr addrspace(1) undef
377   %fortytwo.seven = call float @llvm.ldexp.f32.i32(float 42.0, i32 73)
378   store volatile float %fortytwo.seven, ptr addrspace(1) undef
380   ret void
383 ; Technically we should probably flush these depending on the expected
384 ; denormal mode of the function, but no other IR constant folding
385 ; considers this.
386 define void @ldexp_f32_denormal() {
387 ; CHECK-LABEL: @ldexp_f32_denormal(
388 ; CHECK-NEXT:    store volatile float 0x380FFFFFC0000000, ptr addrspace(1) undef, align 4
389 ; CHECK-NEXT:    store volatile float 0x381FFFFFC0000000, ptr addrspace(1) undef, align 4
390 ; CHECK-NEXT:    ret void
392   %denormal.0 = call float @llvm.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 0)
393   store volatile float %denormal.0, ptr addrspace(1) undef
395   %denormal.1 = call float @llvm.ldexp.f32.i32(float 0x380FFFFFC0000000, i32 1)
396   store volatile float %denormal.1, ptr addrspace(1) undef
398   ret void
401 define void @ldexp_f64() {
402 ; CHECK-LABEL: @ldexp_f64(
403 ; CHECK-NEXT:    store volatile double 2.000000e+00, ptr addrspace(1) undef, align 8
404 ; CHECK-NEXT:    store volatile double 4.000000e+00, ptr addrspace(1) undef, align 8
405 ; CHECK-NEXT:    store volatile double 0x44D5000000000000, ptr addrspace(1) undef, align 8
406 ; CHECK-NEXT:    ret void
408   %one.one = call double @llvm.ldexp.f64.i32(double 1.0, i32 1)
409   store volatile double %one.one, ptr addrspace(1) undef
411   %one.two = call double @llvm.ldexp.f64.i32(double 1.0, i32 2)
412   store volatile double %one.two, ptr addrspace(1) undef
414   %fortytwo.seven = call double @llvm.ldexp.f64.i32(double 42.0, i32 73)
415   store volatile double %fortytwo.seven, ptr addrspace(1) undef
417   ret void
420 define void @ldexp_f16() {
421 ; CHECK-LABEL: @ldexp_f16(
422 ; CHECK-NEXT:    store volatile half 0xH4000, ptr addrspace(1) undef, align 2
423 ; CHECK-NEXT:    store volatile half 0xH4400, ptr addrspace(1) undef, align 2
424 ; CHECK-NEXT:    store volatile half 0xH7C00, ptr addrspace(1) undef, align 2
425 ; CHECK-NEXT:    ret void
427   %one.one = call half @llvm.ldexp.f16.i32(half 1.0, i32 1)
428   store volatile half %one.one, ptr addrspace(1) undef
430   %one.two = call half @llvm.ldexp.f16.i32(half 1.0, i32 2)
431   store volatile half %one.two, ptr addrspace(1) undef
433   %fortytwo.seven = call half @llvm.ldexp.f16.i32(half 42.0, i32 73)
434   store volatile half %fortytwo.seven, ptr addrspace(1) undef
436   ret void
439 define void @ldexp_ppcf128() {
440 ; CHECK-LABEL: @ldexp_ppcf128(
441 ; CHECK-NEXT:    store volatile ppc_fp128 0xMFFF00000000000000000000000000000, ptr addrspace(1) undef, align 16
442 ; CHECK-NEXT:    store volatile ppc_fp128 0xMFFFC0000000000000000000000000000, ptr addrspace(1) undef, align 16
443 ; CHECK-NEXT:    store volatile ppc_fp128 0xM3FD00000000000000000000000000000, ptr addrspace(1) undef, align 16
444 ; CHECK-NEXT:    store volatile ppc_fp128 0xM41700000000000000000000000000000, ptr addrspace(1) undef, align 16
445 ; CHECK-NEXT:    store volatile ppc_fp128 0xMC0700000000000000000000000000000, ptr addrspace(1) undef, align 16
446 ; CHECK-NEXT:    ret void
448   %neginf = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 0xMFFF00000000000000000000000000000, i32 0)
449   store volatile ppc_fp128 %neginf, ptr addrspace(1) undef
451   %snan = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 0xMFFFC0000000000000000000000000000, i32 0)
452   store volatile ppc_fp128 %snan, ptr addrspace(1) undef
454   %one.neg2 = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 0xM3FF00000000000000000000000000000, i32 -2)
455   store volatile ppc_fp128 %one.neg2, ptr addrspace(1) undef
457   %one.24 = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 0xM3FF00000000000000000000000000000, i32 24)
458   store volatile ppc_fp128 %one.24, ptr addrspace(1) undef
460   %negone.8 = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 0xMBFF00000000000000000000000000000, i32 8)
461   store volatile ppc_fp128 %negone.8, ptr addrspace(1) undef
463   ret void
466 define void @constant_fold_ldexp_f32_val_strictfp(i32 %y) #0 {
467 ; CHECK-LABEL: @constant_fold_ldexp_f32_val_strictfp(
468 ; CHECK-NEXT:    [[SNAN_MAY_TRAP:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 3, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
469 ; CHECK-NEXT:    store volatile float [[SNAN_MAY_TRAP]], ptr addrspace(1) undef, align 4
470 ; CHECK-NEXT:    [[SNAN_MAY_NOT_TRAP:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 3, metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
471 ; CHECK-NEXT:    store volatile float [[SNAN_MAY_NOT_TRAP]], ptr addrspace(1) undef, align 4
472 ; CHECK-NEXT:    [[UNKNOWN_ROUNDING:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.500000e+00, i32 42, metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
473 ; CHECK-NEXT:    store volatile float [[UNKNOWN_ROUNDING]], ptr addrspace(1) undef, align 4
474 ; CHECK-NEXT:    [[NORMAL:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.500000e+00, i32 42, metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
475 ; CHECK-NEXT:    store volatile float [[NORMAL]], ptr addrspace(1) undef, align 4
476 ; CHECK-NEXT:    [[NORMAL_DOWN:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.500000e+00, i32 42, metadata !"round.downward", metadata !"fpexcept.ignore") #[[ATTR0]]
477 ; CHECK-NEXT:    store volatile float [[NORMAL_DOWN]], ptr addrspace(1) undef, align 4
478 ; CHECK-NEXT:    ret void
480   %snan.may.trap = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 3, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
481   store volatile float %snan.may.trap, ptr addrspace(1) undef
483   %snan.may.not.trap = call float @llvm.experimental.constrained.ldexp.f32.i32(float 0x7FF0000020000000, i32 3, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
484   store volatile float %snan.may.not.trap, ptr addrspace(1) undef
486   %unknown.rounding = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.5, i32 42, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
487   store volatile float %unknown.rounding, ptr addrspace(1) undef
489   %normal = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.5, i32 42, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
490   store volatile float %normal, ptr addrspace(1) undef
492   %normal.down = call float @llvm.experimental.constrained.ldexp.f32.i32(float 2.5, i32 42, metadata !"round.downward", metadata !"fpexcept.ignore") #0
493   store volatile float %normal.down, ptr addrspace(1) undef
495   ret void
498 declare half @llvm.ldexp.f16.i32(half, i32) #1
499 declare float @llvm.ldexp.f32.i32(float, i32) #1
500 declare double @llvm.ldexp.f64.i32(double, i32) #1
501 declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float>, <2 x i32>) #1
502 declare float @llvm.experimental.constrained.ldexp.f32.i32(float, i32, metadata, metadata) #1
503 declare ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128, i32) #1
505 attributes #0 = { strictfp }
506 attributes #1 = { nounwind readnone speculatable }