[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstCombine / AMDGPU / ldexp.ll
blobdbcecb6538cc161fe0fb6477c25cdf02b21db995
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -mtriple=amdgcn-amd-amdhsa -instcombine -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.amdgcn.ldexp.f32(float undef, i32 undef)
9   ret float %call
12 ; If the exponent is 0, it doesn't matter if the first argument is
13 ; constant or not.
14 define void @ldexp_f32_exp0(float %x) {
15 ; CHECK-LABEL: @ldexp_f32_exp0(
16 ; CHECK-NEXT:    store volatile float [[X:%.*]], float addrspace(1)* undef, align 4
17 ; CHECK-NEXT:    store volatile float [[X]], float addrspace(1)* undef, align 4
18 ; CHECK-NEXT:    [[ONE:%.*]] = call float @llvm.amdgcn.ldexp.f32(float [[X]], i32 1)
19 ; CHECK-NEXT:    store volatile float [[ONE]], float addrspace(1)* undef, align 4
20 ; CHECK-NEXT:    ret void
22   %zero = call float @llvm.amdgcn.ldexp.f32(float %x, i32 0)
23   store volatile float %zero, float addrspace(1)* undef
25   %undef = call float @llvm.amdgcn.ldexp.f32(float %x, i32 undef)
26   store volatile float %undef, float addrspace(1)* undef
28   %one = call float @llvm.amdgcn.ldexp.f32(float %x, i32 1)
29   store volatile float %one, float addrspace(1)* undef
30   ret void
33 ; Test variable exponent but zero or undef value.
34 define void @ldexp_f32_val0(i32 %y) {
35 ; CHECK-LABEL: @ldexp_f32_val0(
36 ; CHECK-NEXT:    store volatile float 0.000000e+00, float addrspace(1)* undef, align 4
37 ; CHECK-NEXT:    store volatile float -0.000000e+00, float addrspace(1)* undef, align 4
38 ; CHECK-NEXT:    store volatile float 0x7FF8000000000000, float addrspace(1)* undef, align 4
39 ; CHECK-NEXT:    ret void
41   %zero = call float @llvm.amdgcn.ldexp.f32(float 0.0, i32 %y)
42   store volatile float %zero, float addrspace(1)* undef
44   %neg.zero = call float @llvm.amdgcn.ldexp.f32(float -0.0, i32 %y)
45   store volatile float %neg.zero, float addrspace(1)* undef
47   %undef = call float @llvm.amdgcn.ldexp.f32(float undef, i32 %y)
48   store volatile float %undef, float addrspace(1)* undef
49   ret void
52 define void @ldexp_f32_val_infinity(i32 %y) {
53 ; CHECK-LABEL: @ldexp_f32_val_infinity(
54 ; CHECK-NEXT:    store volatile float 0x7FF0000000000000, float addrspace(1)* undef, align 4
55 ; CHECK-NEXT:    store volatile float 0xFFF0000000000000, float addrspace(1)* undef, align 4
56 ; CHECK-NEXT:    store volatile float 0x7FF0000000000000, float addrspace(1)* undef, align 4
57 ; CHECK-NEXT:    store volatile float 0xFFF0000000000000, float addrspace(1)* undef, align 4
58 ; CHECK-NEXT:    ret void
60   %inf = call float @llvm.amdgcn.ldexp.f32(float 0x7ff0000000000000, i32 %y)
61   store volatile float %inf, float addrspace(1)* undef
63   %neg.inf = call float @llvm.amdgcn.ldexp.f32(float 0xfff0000000000000, i32 %y)
64   store volatile float %neg.inf, float addrspace(1)* undef
66   %inf.zero = call float @llvm.amdgcn.ldexp.f32(float 0x7ff0000000000000, i32 0)
67   store volatile float %inf.zero, float addrspace(1)* undef
69   %neg.inf.zero = call float @llvm.amdgcn.ldexp.f32(float 0xfff0000000000000, i32 0)
70   store volatile float %neg.inf.zero, float addrspace(1)* undef
72   ret void
75 ; Signaling nan should be quieted.
76 ; Technically this depends on the ieee_mode in the mode register.
77 define void @ldexp_f32_val_nan(i32 %y) {
78 ; CHECK-LABEL: @ldexp_f32_val_nan(
79 ; CHECK-NEXT:    store volatile float 0x7FF8001000000000, float addrspace(1)* undef, align 4
80 ; CHECK-NEXT:    store volatile float 0xFFF8000100000000, float addrspace(1)* undef, align 4
81 ; CHECK-NEXT:    store volatile float 0x7FF8000020000000, float addrspace(1)* undef, align 4
82 ; CHECK-NEXT:    store volatile float 0xFFFFFFFFE0000000, float addrspace(1)* undef, align 4
83 ; CHECK-NEXT:    ret void
85   %plus.qnan = call float @llvm.amdgcn.ldexp.f32(float 0x7ff0001000000000, i32 %y)
86   store volatile float %plus.qnan, float addrspace(1)* undef
88   %neg.qnan = call float @llvm.amdgcn.ldexp.f32(float 0xfff0000100000000, i32 %y)
89   store volatile float %neg.qnan, float addrspace(1)* undef
91   %plus.snan = call float @llvm.amdgcn.ldexp.f32(float 0x7FF0000020000000, i32 %y)
92   store volatile float %plus.snan, float addrspace(1)* undef
94   %neg.snan = call float @llvm.amdgcn.ldexp.f32(float 0xFFF7FFFFE0000000, i32 %y)
95   store volatile float %neg.snan, float addrspace(1)* undef
97   ret void
100 define void @ldexp_f32_val_nan_strictfp(i32 %y) #0 {
101 ; CHECK-LABEL: @ldexp_f32_val_nan_strictfp(
102 ; CHECK-NEXT:    [[PLUS_QNAN:%.*]] = call float @llvm.amdgcn.ldexp.f32(float 0x7FF0001000000000, i32 [[Y:%.*]]) [[ATTR0:#.*]]
103 ; CHECK-NEXT:    store volatile float [[PLUS_QNAN]], float addrspace(1)* undef, align 4
104 ; CHECK-NEXT:    [[NEG_QNAN:%.*]] = call float @llvm.amdgcn.ldexp.f32(float 0xFFF0000100000000, i32 [[Y]]) [[ATTR0]]
105 ; CHECK-NEXT:    store volatile float [[NEG_QNAN]], float addrspace(1)* undef, align 4
106 ; CHECK-NEXT:    [[PLUS_SNAN:%.*]] = call float @llvm.amdgcn.ldexp.f32(float 0x7FF0000020000000, i32 [[Y]]) [[ATTR0]]
107 ; CHECK-NEXT:    store volatile float [[PLUS_SNAN]], float addrspace(1)* undef, align 4
108 ; CHECK-NEXT:    [[NEG_SNAN:%.*]] = call float @llvm.amdgcn.ldexp.f32(float 0xFFF7FFFFE0000000, i32 [[Y]]) [[ATTR0]]
109 ; CHECK-NEXT:    store volatile float [[NEG_SNAN]], float addrspace(1)* undef, align 4
110 ; CHECK-NEXT:    store volatile float 0x7FF8000000000000, float addrspace(1)* undef, align 4
111 ; CHECK-NEXT:    ret void
113   %plus.qnan = call float @llvm.amdgcn.ldexp.f32(float 0x7ff0001000000000, i32 %y) #0
114   store volatile float %plus.qnan, float addrspace(1)* undef
116   %neg.qnan = call float @llvm.amdgcn.ldexp.f32(float 0xfff0000100000000, i32 %y) #0
117   store volatile float %neg.qnan, float addrspace(1)* undef
119   %plus.snan = call float @llvm.amdgcn.ldexp.f32(float 0x7FF0000020000000, i32 %y) #0
120   store volatile float %plus.snan, float addrspace(1)* undef
122   %neg.snan = call float @llvm.amdgcn.ldexp.f32(float 0xFFF7FFFFE0000000, i32 %y) #0
123   store volatile float %neg.snan, float addrspace(1)* undef
125   %undef = call float @llvm.amdgcn.ldexp.f32(float undef, i32 %y) #0
126   store volatile float %undef, float addrspace(1)* undef
128   ret void
131 define void @ldexp_f32_0() {
132 ; CHECK-LABEL: @ldexp_f32_0(
133 ; CHECK-NEXT:    store volatile float 0.000000e+00, float addrspace(1)* undef, align 4
134 ; CHECK-NEXT:    store volatile float -0.000000e+00, float addrspace(1)* undef, align 4
135 ; CHECK-NEXT:    store volatile float 0.000000e+00, float addrspace(1)* undef, align 4
136 ; CHECK-NEXT:    store volatile float 0.000000e+00, float addrspace(1)* undef, align 4
137 ; CHECK-NEXT:    store volatile float 0.000000e+00, float addrspace(1)* undef, align 4
138 ; CHECK-NEXT:    store volatile float 0.000000e+00, float addrspace(1)* undef, align 4
139 ; CHECK-NEXT:    store volatile float 0.000000e+00, float addrspace(1)* undef, align 4
140 ; CHECK-NEXT:    ret void
142   %zero = call float @llvm.amdgcn.ldexp.f32(float 0.0, i32 0)
143   store volatile float %zero, float addrspace(1)* undef
145   %neg.zero = call float @llvm.amdgcn.ldexp.f32(float -0.0, i32 0)
146   store volatile float %neg.zero, float addrspace(1)* undef
148   %one = call float @llvm.amdgcn.ldexp.f32(float 0.0, i32 1)
149   store volatile float %one, float addrspace(1)* undef
151   %min.exp = call float @llvm.amdgcn.ldexp.f32(float 0.0, i32 -126)
152   store volatile float %min.exp, float addrspace(1)* undef
154   %min.exp.sub1 = call float @llvm.amdgcn.ldexp.f32(float 0.0, i32 -127)
155   store volatile float %min.exp.sub1, float addrspace(1)* undef
157   %max.exp = call float @llvm.amdgcn.ldexp.f32(float 0.0, i32 127)
158   store volatile float %max.exp, float addrspace(1)* undef
160   %max.exp.plus1 = call float @llvm.amdgcn.ldexp.f32(float 0.0, i32 128)
161   store volatile float %max.exp.plus1, float addrspace(1)* undef
163   ret void
166 ; Should be able to ignore strictfp in this case
167 define void @ldexp_f32_0_strictfp(float %x) #0 {
168 ; CHECK-LABEL: @ldexp_f32_0_strictfp(
169 ; CHECK-NEXT:    store volatile float 0.000000e+00, float addrspace(1)* undef, align 4
170 ; CHECK-NEXT:    store volatile float -0.000000e+00, float addrspace(1)* undef, align 4
171 ; CHECK-NEXT:    store volatile float 0.000000e+00, float addrspace(1)* undef, align 4
172 ; CHECK-NEXT:    [[UNKNOWN_ZERO:%.*]] = call float @llvm.amdgcn.ldexp.f32(float [[X:%.*]], i32 0) [[ATTR0]]
173 ; CHECK-NEXT:    store volatile float [[UNKNOWN_ZERO]], float addrspace(1)* undef, align 4
174 ; CHECK-NEXT:    [[UNKNOWN_UNDEF:%.*]] = call float @llvm.amdgcn.ldexp.f32(float [[X]], i32 undef) [[ATTR0]]
175 ; CHECK-NEXT:    store volatile float [[UNKNOWN_UNDEF]], float addrspace(1)* undef, align 4
176 ; CHECK-NEXT:    [[DENORMAL_0:%.*]] = call float @llvm.amdgcn.ldexp.f32(float 0x380FFFFFC0000000, i32 0) [[ATTR0]]
177 ; CHECK-NEXT:    store volatile float [[DENORMAL_0]], float addrspace(1)* undef, align 4
178 ; CHECK-NEXT:    [[DENORMAL_1:%.*]] = call float @llvm.amdgcn.ldexp.f32(float 0x380FFFFFC0000000, i32 1) [[ATTR0]]
179 ; CHECK-NEXT:    store volatile float [[DENORMAL_1]], float addrspace(1)* undef, align 4
180 ; CHECK-NEXT:    ret void
182   %zero = call float @llvm.amdgcn.ldexp.f32(float 0.0, i32 0) #0
183   store volatile float %zero, float addrspace(1)* undef
185   %neg.zero = call float @llvm.amdgcn.ldexp.f32(float -0.0, i32 0) #0
186   store volatile float %neg.zero, float addrspace(1)* undef
188   %one = call float @llvm.amdgcn.ldexp.f32(float 0.0, i32 1) #0
189   store volatile float %one, float addrspace(1)* undef
191   %unknown.zero = call float @llvm.amdgcn.ldexp.f32(float %x, i32 0) #0
192   store volatile float %unknown.zero, float addrspace(1)* undef
194   %unknown.undef = call float @llvm.amdgcn.ldexp.f32(float %x, i32 undef) #0
195   store volatile float %unknown.undef, float addrspace(1)* undef
197   %denormal.0 = call float @llvm.amdgcn.ldexp.f32(float 0x380FFFFFC0000000, i32 0) #0
198   store volatile float %denormal.0, float addrspace(1)* undef
200   %denormal.1 = call float @llvm.amdgcn.ldexp.f32(float 0x380FFFFFC0000000, i32 1) #0
201   store volatile float %denormal.1, float addrspace(1)* undef
203   ret void
206 define void @ldexp_f32() {
207 ; CHECK-LABEL: @ldexp_f32(
208 ; CHECK-NEXT:    store volatile float 2.000000e+00, float addrspace(1)* undef, align 4
209 ; CHECK-NEXT:    store volatile float 4.000000e+00, float addrspace(1)* undef, align 4
210 ; CHECK-NEXT:    store volatile float 8.000000e+00, float addrspace(1)* undef, align 4
211 ; CHECK-NEXT:    store volatile float 5.000000e-01, float addrspace(1)* undef, align 4
212 ; CHECK-NEXT:    store volatile float 0x3810000000000000, float addrspace(1)* undef, align 4
213 ; CHECK-NEXT:    store volatile float 0x3800000000000000, float addrspace(1)* undef, align 4
214 ; CHECK-NEXT:    store volatile float 0x47E0000000000000, float addrspace(1)* undef, align 4
215 ; CHECK-NEXT:    store volatile float 0x7FF0000000000000, float addrspace(1)* undef, align 4
216 ; CHECK-NEXT:    store volatile float -2.000000e+00, float addrspace(1)* undef, align 4
217 ; CHECK-NEXT:    store volatile float -4.000000e+00, float addrspace(1)* undef, align 4
218 ; CHECK-NEXT:    store volatile float -8.000000e+00, float addrspace(1)* undef, align 4
219 ; CHECK-NEXT:    store volatile float -5.000000e-01, float addrspace(1)* undef, align 4
220 ; CHECK-NEXT:    store volatile float 0xB810000000000000, float addrspace(1)* undef, align 4
221 ; CHECK-NEXT:    store volatile float 0xB800000000000000, float addrspace(1)* undef, align 4
222 ; CHECK-NEXT:    store volatile float 0xC7E0000000000000, float addrspace(1)* undef, align 4
223 ; CHECK-NEXT:    store volatile float 0xFFF0000000000000, float addrspace(1)* undef, align 4
224 ; CHECK-NEXT:    store volatile float 0x44D5000000000000, float addrspace(1)* undef, align 4
225 ; CHECK-NEXT:    ret void
227   %one.one = call float @llvm.amdgcn.ldexp.f32(float 1.0, i32 1)
228   store volatile float %one.one, float addrspace(1)* undef
230   %one.two = call float @llvm.amdgcn.ldexp.f32(float 1.0, i32 2)
231   store volatile float %one.two, float addrspace(1)* undef
233   %one.three = call float @llvm.amdgcn.ldexp.f32(float 1.0, i32 3)
234   store volatile float %one.three, float addrspace(1)* undef
236   %one.negone = call float @llvm.amdgcn.ldexp.f32(float 1.0, i32 -1)
237   store volatile float %one.negone, float addrspace(1)* undef
239   %one.min.exp = call float @llvm.amdgcn.ldexp.f32(float 1.0, i32 -126)
240   store volatile float %one.min.exp, float addrspace(1)* undef
242   %one.min.exp.sub1 = call float @llvm.amdgcn.ldexp.f32(float 1.0, i32 -127)
243   store volatile float %one.min.exp.sub1, float addrspace(1)* undef
245   %one.max.exp = call float @llvm.amdgcn.ldexp.f32(float 1.0, i32 127)
246   store volatile float %one.max.exp, float addrspace(1)* undef
248   %one.max.exp.plus1 = call float @llvm.amdgcn.ldexp.f32(float 1.0, i32 128)
249   store volatile float %one.max.exp.plus1, float addrspace(1)* undef
251   %neg.one.one = call float @llvm.amdgcn.ldexp.f32(float -1.0, i32 1)
252   store volatile float %neg.one.one, float addrspace(1)* undef
254   %neg.one.two = call float @llvm.amdgcn.ldexp.f32(float -1.0, i32 2)
255   store volatile float %neg.one.two, float addrspace(1)* undef
257   %neg.one.three = call float @llvm.amdgcn.ldexp.f32(float -1.0, i32 3)
258   store volatile float %neg.one.three, float addrspace(1)* undef
260   %neg.one.negone = call float @llvm.amdgcn.ldexp.f32(float -1.0, i32 -1)
261   store volatile float %neg.one.negone, float addrspace(1)* undef
263   %neg.one.min.exp = call float @llvm.amdgcn.ldexp.f32(float -1.0, i32 -126)
264   store volatile float %neg.one.min.exp, float addrspace(1)* undef
266   %neg.one.min.exp.sub1 = call float @llvm.amdgcn.ldexp.f32(float -1.0, i32 -127)
267   store volatile float %neg.one.min.exp.sub1, float addrspace(1)* undef
269   %neg.one.max.exp = call float @llvm.amdgcn.ldexp.f32(float -1.0, i32 127)
270   store volatile float %neg.one.max.exp, float addrspace(1)* undef
272   %neg.one.max.exp.plus1 = call float @llvm.amdgcn.ldexp.f32(float -1.0, i32 128)
273   store volatile float %neg.one.max.exp.plus1, float addrspace(1)* undef
275   %fortytwo.seven = call float @llvm.amdgcn.ldexp.f32(float 42.0, i32 73)
276   store volatile float %fortytwo.seven, float addrspace(1)* undef
278   ret void
281 ; Technically we should probably flush these depending on the expected
282 ; denormal mode of the function, but no other IR constant folding
283 ; considers this.
284 define void @ldexp_f32_denormal() {
285 ; CHECK-LABEL: @ldexp_f32_denormal(
286 ; CHECK-NEXT:    store volatile float 0x380FFFFFC0000000, float addrspace(1)* undef, align 4
287 ; CHECK-NEXT:    store volatile float 0x381FFFFFC0000000, float addrspace(1)* undef, align 4
288 ; CHECK-NEXT:    ret void
290   %denormal.0 = call float @llvm.amdgcn.ldexp.f32(float 0x380FFFFFC0000000, i32 0)
291   store volatile float %denormal.0, float addrspace(1)* undef
293   %denormal.1 = call float @llvm.amdgcn.ldexp.f32(float 0x380FFFFFC0000000, i32 1)
294   store volatile float %denormal.1, float addrspace(1)* undef
296   ret void
299 define void @ldexp_f64() {
300 ; CHECK-LABEL: @ldexp_f64(
301 ; CHECK-NEXT:    store volatile double 2.000000e+00, double addrspace(1)* undef, align 8
302 ; CHECK-NEXT:    store volatile double 4.000000e+00, double addrspace(1)* undef, align 8
303 ; CHECK-NEXT:    store volatile double 0x44D5000000000000, double addrspace(1)* undef, align 8
304 ; CHECK-NEXT:    ret void
306   %one.one = call double @llvm.amdgcn.ldexp.f64(double 1.0, i32 1)
307   store volatile double %one.one, double addrspace(1)* undef
309   %one.two = call double @llvm.amdgcn.ldexp.f64(double 1.0, i32 2)
310   store volatile double %one.two, double addrspace(1)* undef
312   %fortytwo.seven = call double @llvm.amdgcn.ldexp.f64(double 42.0, i32 73)
313   store volatile double %fortytwo.seven, double addrspace(1)* undef
315   ret void
318 define void @ldexp_f16() {
319 ; CHECK-LABEL: @ldexp_f16(
320 ; CHECK-NEXT:    store volatile half 0xH4000, half addrspace(1)* undef, align 2
321 ; CHECK-NEXT:    store volatile half 0xH4400, half addrspace(1)* undef, align 2
322 ; CHECK-NEXT:    store volatile half 0xH7C00, half addrspace(1)* undef, align 2
323 ; CHECK-NEXT:    ret void
325   %one.one = call half @llvm.amdgcn.ldexp.f16(half 1.0, i32 1)
326   store volatile half %one.one, half addrspace(1)* undef
328   %one.two = call half @llvm.amdgcn.ldexp.f16(half 1.0, i32 2)
329   store volatile half %one.two, half addrspace(1)* undef
331   %fortytwo.seven = call half @llvm.amdgcn.ldexp.f16(half 42.0, i32 73)
332   store volatile half %fortytwo.seven, half addrspace(1)* undef
334   ret void
337 declare half @llvm.amdgcn.ldexp.f16(half, i32) #1
338 declare float @llvm.amdgcn.ldexp.f32(float, i32) #1
339 declare double @llvm.amdgcn.ldexp.f64(double, i32) #1
341 attributes #0 = { strictfp }
342 attributes #1 = { nounwind readnone speculatable }