1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instsimplify -S | FileCheck %s
5 ; Verify that floor(10.1) is folded to 10.0 when the exception behavior is 'ignore'.
6 define double @floor_01() #0 {
7 ; CHECK-LABEL: @floor_01(
9 ; CHECK-NEXT: ret double 1.000000e+01
12 %result = call double @llvm.experimental.constrained.floor.f64(double 1.010000e+01, metadata !"fpexcept.ignore") #0
16 ; Verify that floor(-10.1) is folded to -11.0 when the exception behavior is not 'ignore'.
17 define double @floor_02() #0 {
18 ; CHECK-LABEL: @floor_02(
20 ; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.floor.f64(double -1.010000e+01, metadata !"fpexcept.strict") #[[ATTR0:[0-9]+]]
21 ; CHECK-NEXT: ret double -1.100000e+01
24 %result = call double @llvm.experimental.constrained.floor.f64(double -1.010000e+01, metadata !"fpexcept.strict") #0
28 ; Verify that ceil(10.1) is folded to 11.0 when the exception behavior is 'ignore'.
29 define double @ceil_01() #0 {
30 ; CHECK-LABEL: @ceil_01(
32 ; CHECK-NEXT: ret double 1.100000e+01
35 %result = call double @llvm.experimental.constrained.ceil.f64(double 1.010000e+01, metadata !"fpexcept.ignore") #0
39 ; Verify that ceil(-10.1) is folded to -10.0 when the exception behavior is not 'ignore'.
40 define double @ceil_02() #0 {
41 ; CHECK-LABEL: @ceil_02(
43 ; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.ceil.f64(double -1.010000e+01, metadata !"fpexcept.strict") #[[ATTR0]]
44 ; CHECK-NEXT: ret double -1.000000e+01
47 %result = call double @llvm.experimental.constrained.ceil.f64(double -1.010000e+01, metadata !"fpexcept.strict") #0
51 ; Verify that trunc(10.1) is folded to 10.0 when the exception behavior is 'ignore'.
52 define double @trunc_01() #0 {
53 ; CHECK-LABEL: @trunc_01(
55 ; CHECK-NEXT: ret double 1.000000e+01
58 %result = call double @llvm.experimental.constrained.trunc.f64(double 1.010000e+01, metadata !"fpexcept.ignore") #0
62 ; Verify that trunc(-10.1) is folded to -10.0 when the exception behavior is NOT 'ignore'.
63 define double @trunc_02() #0 {
64 ; CHECK-LABEL: @trunc_02(
66 ; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.trunc.f64(double -1.010000e+01, metadata !"fpexcept.strict") #[[ATTR0]]
67 ; CHECK-NEXT: ret double -1.000000e+01
70 %result = call double @llvm.experimental.constrained.trunc.f64(double -1.010000e+01, metadata !"fpexcept.strict") #0
74 ; Verify that round(10.5) is folded to 11.0 when the exception behavior is 'ignore'.
75 define double @round_01() #0 {
76 ; CHECK-LABEL: @round_01(
78 ; CHECK-NEXT: ret double 1.100000e+01
81 %result = call double @llvm.experimental.constrained.round.f64(double 1.050000e+01, metadata !"fpexcept.ignore") #0
85 ; Verify that floor(-10.5) is folded to -11.0 when the exception behavior is NOT 'ignore'.
86 define double @round_02() #0 {
87 ; CHECK-LABEL: @round_02(
89 ; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.round.f64(double -1.050000e+01, metadata !"fpexcept.strict") #[[ATTR0]]
90 ; CHECK-NEXT: ret double -1.100000e+01
93 %result = call double @llvm.experimental.constrained.round.f64(double -1.050000e+01, metadata !"fpexcept.strict") #0
97 ; Verify that nearbyint(10.5) is folded to 11.0 when the rounding mode is 'upward'.
98 define double @nearbyint_01() #0 {
99 ; CHECK-LABEL: @nearbyint_01(
101 ; CHECK-NEXT: ret double 1.100000e+01
104 %result = call double @llvm.experimental.constrained.nearbyint.f64(double 1.050000e+01, metadata !"round.upward", metadata !"fpexcept.ignore") #0
108 ; Verify that nearbyint(10.5) is folded to 10.0 when the rounding mode is 'downward'.
109 define double @nearbyint_02() #0 {
110 ; CHECK-LABEL: @nearbyint_02(
112 ; CHECK-NEXT: ret double 1.000000e+01
115 %result = call double @llvm.experimental.constrained.nearbyint.f64(double 1.050000e+01, metadata !"round.downward", metadata !"fpexcept.maytrap") #0
119 ; Verify that nearbyint(10.5) is folded to 10.0 when the rounding mode is 'towardzero'.
120 define double @nearbyint_03() #0 {
121 ; CHECK-LABEL: @nearbyint_03(
123 ; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.nearbyint.f64(double 1.050000e+01, metadata !"round.towardzero", metadata !"fpexcept.strict") #[[ATTR0]]
124 ; CHECK-NEXT: ret double 1.000000e+01
127 %result = call double @llvm.experimental.constrained.nearbyint.f64(double 1.050000e+01, metadata !"round.towardzero", metadata !"fpexcept.strict") #0
131 ; Verify that nearbyint(10.5) is folded to 10.0 when the rounding mode is 'tonearest'.
132 define double @nearbyint_04() #0 {
133 ; CHECK-LABEL: @nearbyint_04(
135 ; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.nearbyint.f64(double 1.050000e+01, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
136 ; CHECK-NEXT: ret double 1.000000e+01
139 %result = call double @llvm.experimental.constrained.nearbyint.f64(double 1.050000e+01, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
143 ; Verify that nearbyint(10.5) is NOT folded if the rounding mode is 'dynamic'.
144 define double @nearbyint_05() #0 {
145 ; CHECK-LABEL: @nearbyint_05(
147 ; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.nearbyint.f64(double 1.050000e+01, metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]]
148 ; CHECK-NEXT: ret double [[RESULT]]
151 %result = call double @llvm.experimental.constrained.nearbyint.f64(double 1.050000e+01, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
155 ; Verify that trunc(SNAN) is NOT folded if the exception behavior mode is not 'ignore'.
156 define double @nonfinite_01() #0 {
157 ; CHECK-LABEL: @nonfinite_01(
159 ; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.trunc.f64(double 0x7FF4000000000000, metadata !"fpexcept.strict") #[[ATTR0]]
160 ; CHECK-NEXT: ret double [[RESULT]]
163 %result = call double @llvm.experimental.constrained.trunc.f64(double 0x7ff4000000000000, metadata !"fpexcept.strict") #0
167 ; Verify that trunc(SNAN) is folded to QNAN if the exception behavior mode is 'ignore'.
168 define double @nonfinite_02() #0 {
169 ; CHECK-LABEL: @nonfinite_02(
171 ; CHECK-NEXT: ret double 0x7FF8000000000000
174 %result = call double @llvm.experimental.constrained.trunc.f64(double 0x7ff4000000000000, metadata !"fpexcept.ignore") #0
178 ; Verify that trunc(QNAN) is folded even if the exception behavior mode is not 'ignore'.
179 define double @nonfinite_03() #0 {
180 ; CHECK-LABEL: @nonfinite_03(
182 ; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.trunc.f64(double 0x7FF8000000000000, metadata !"fpexcept.strict") #[[ATTR0]]
183 ; CHECK-NEXT: ret double 0x7FF8000000000000
186 %result = call double @llvm.experimental.constrained.trunc.f64(double 0x7ff8000000000000, metadata !"fpexcept.strict") #0
190 ; Verify that trunc(+Inf) is folded even if the exception behavior mode is not 'ignore'.
191 define double @nonfinite_04() #0 {
192 ; CHECK-LABEL: @nonfinite_04(
194 ; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.trunc.f64(double 0x7FF0000000000000, metadata !"fpexcept.strict") #[[ATTR0]]
195 ; CHECK-NEXT: ret double 0x7FF0000000000000
198 %result = call double @llvm.experimental.constrained.trunc.f64(double 0x7ff0000000000000, metadata !"fpexcept.strict") #0
202 ; Verify that rint(10) is folded to 10.0 when the rounding mode is 'tonearest'.
203 define double @rint_01() #0 {
204 ; CHECK-LABEL: @rint_01(
206 ; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.rint.f64(double 1.000000e+01, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
207 ; CHECK-NEXT: ret double 1.000000e+01
210 %result = call double @llvm.experimental.constrained.rint.f64(double 1.000000e+01, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
214 ; Verify that rint(10.1) is NOT folded to 10.0 when the exception behavior is 'strict'.
215 define double @rint_02() #0 {
216 ; CHECK-LABEL: @rint_02(
218 ; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.rint.f64(double 1.010000e+01, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
219 ; CHECK-NEXT: ret double [[RESULT]]
222 %result = call double @llvm.experimental.constrained.rint.f64(double 1.010000e+01, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
226 ; Verify that rint(10.1) is folded to 10.0 when the exception behavior is not 'strict'.
227 define double @rint_03() #0 {
228 ; CHECK-LABEL: @rint_03(
230 ; CHECK-NEXT: ret double 1.000000e+01
233 %result = call double @llvm.experimental.constrained.rint.f64(double 1.010000e+01, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
237 define float @fadd_01() #0 {
238 ; CHECK-LABEL: @fadd_01(
240 ; CHECK-NEXT: ret float 3.000000e+01
243 %result = call float @llvm.experimental.constrained.fadd.f32(float 1.000000e+01, float 2.000000e+01, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
247 ; Inexact result does not prevent from folding if exceptions are ignored and
248 ; rounding mode is known.
249 define double @fadd_02() #0 {
250 ; CHECK-LABEL: @fadd_02(
252 ; CHECK-NEXT: ret double 2.000000e+00
255 %result = call double @llvm.experimental.constrained.fadd.f64(double 1.0, double 0x3FF0000000000001, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
259 define double @fadd_03() #0 {
260 ; CHECK-LABEL: @fadd_03(
262 ; CHECK-NEXT: ret double 0x4000000000000001
265 %result = call double @llvm.experimental.constrained.fadd.f64(double 1.0, double 0x3FF0000000000001, metadata !"round.upward", metadata !"fpexcept.ignore") #0
269 ; Inexact result prevents from folding if exceptions may be checked.
270 define double @fadd_04() #0 {
271 ; CHECK-LABEL: @fadd_04(
273 ; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double 1.000000e+00, double 0x3FF0000000000001, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
274 ; CHECK-NEXT: ret double [[RESULT]]
277 %result = call double @llvm.experimental.constrained.fadd.f64(double 1.0, double 0x3FF0000000000001, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
281 ; If result is exact, folding is allowed even if exceptions may be checked.
282 define double @fadd_05() #0 {
283 ; CHECK-LABEL: @fadd_05(
285 ; CHECK-NEXT: ret double 3.000000e+00
288 %result = call double @llvm.experimental.constrained.fadd.f64(double 1.0, double 2.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
292 ; Dynamic rounding mode does not prevent from folding if the result is exact.
293 define double @fadd_06() #0 {
294 ; CHECK-LABEL: @fadd_06(
296 ; CHECK-NEXT: ret double 3.000000e+00
299 %result = call double @llvm.experimental.constrained.fadd.f64(double 1.0, double 2.0, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
303 ; Inexact results prevents from folding if rounding mode is unknown.
304 define double @fadd_07() #0 {
305 ; CHECK-LABEL: @fadd_07(
307 ; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double 1.000000e+00, double 0x3FF0000000000001, metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
308 ; CHECK-NEXT: ret double [[RESULT]]
311 %result = call double @llvm.experimental.constrained.fadd.f64(double 1.0, double 0x3FF0000000000001, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
315 ; Infinite result does not prevent from folding unless exceptions are tracked.
316 define double @fadd_08() #0 {
317 ; CHECK-LABEL: @fadd_08(
319 ; CHECK-NEXT: ret double 0x7FF0000000000000
322 %result = call double @llvm.experimental.constrained.fadd.f64(double 0x7fEFFFFFFFFFFFFF, double 0x7fEFFFFFFFFFFFFF, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
326 define double @fadd_09() #0 {
327 ; CHECK-LABEL: @fadd_09(
329 ; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double 0x7FEFFFFFFFFFFFFF, double 0x7FEFFFFFFFFFFFFF, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
330 ; CHECK-NEXT: ret double [[RESULT]]
333 %result = call double @llvm.experimental.constrained.fadd.f64(double 0x7fEFFFFFFFFFFFFF, double 0x7fEFFFFFFFFFFFFF, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
337 define half @fadd_10() #0 {
338 ; CHECK-LABEL: @fadd_10(
340 ; CHECK-NEXT: ret half 0xH4200
343 %result = call half @llvm.experimental.constrained.fadd.f16(half 1.0, half 2.0, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
347 define bfloat @fadd_11() #0 {
348 ; CHECK-LABEL: @fadd_11(
350 ; CHECK-NEXT: ret bfloat 0xR4040
353 %result = call bfloat @llvm.experimental.constrained.fadd.bf16(bfloat 1.0, bfloat 2.0, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
357 define double @fsub_01() #0 {
358 ; CHECK-LABEL: @fsub_01(
360 ; CHECK-NEXT: ret double -1.000000e+00
363 %result = call double @llvm.experimental.constrained.fsub.f64(double 1.0, double 2.0, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
367 define double @fmul_01() #0 {
368 ; CHECK-LABEL: @fmul_01(
370 ; CHECK-NEXT: ret double 2.000000e+00
373 %result = call double @llvm.experimental.constrained.fmul.f64(double 1.0, double 2.0, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
377 define double @fdiv_01() #0 {
378 ; CHECK-LABEL: @fdiv_01(
380 ; CHECK-NEXT: ret double 5.000000e-01
383 %result = call double @llvm.experimental.constrained.fdiv.f64(double 1.0, double 2.0, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
387 define double @frem_01() #0 {
388 ; CHECK-LABEL: @frem_01(
390 ; CHECK-NEXT: ret double 1.000000e+00
393 %result = call double @llvm.experimental.constrained.frem.f64(double 1.0, double 2.0, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
397 define double @fma_01() #0 {
398 ; CHECK-LABEL: @fma_01(
400 ; CHECK-NEXT: ret double 5.000000e+00
403 %result = call double @llvm.experimental.constrained.fma.f64(double 1.0, double 2.0, double 3.0, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
407 define double @fmuladd_01() #0 {
408 ; CHECK-LABEL: @fmuladd_01(
410 ; CHECK-NEXT: ret double 5.000000e+00
413 %result = call double @llvm.experimental.constrained.fmuladd.f64(double 1.0, double 2.0, double 3.0, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
418 attributes #0 = { strictfp }
420 declare double @llvm.experimental.constrained.nearbyint.f64(double, metadata, metadata)
421 declare double @llvm.experimental.constrained.floor.f64(double, metadata)
422 declare double @llvm.experimental.constrained.ceil.f64(double, metadata)
423 declare double @llvm.experimental.constrained.trunc.f64(double, metadata)
424 declare double @llvm.experimental.constrained.round.f64(double, metadata)
425 declare double @llvm.experimental.constrained.rint.f64(double, metadata, metadata)
426 declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata)
427 declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata)
428 declare half @llvm.experimental.constrained.fadd.f16(half, half, metadata, metadata)
429 declare bfloat @llvm.experimental.constrained.fadd.bf16(bfloat, bfloat, metadata, metadata)
430 declare double @llvm.experimental.constrained.fsub.f64(double, double, metadata, metadata)
431 declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata)
432 declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata)
433 declare double @llvm.experimental.constrained.frem.f64(double, double, metadata, metadata)
434 declare double @llvm.experimental.constrained.fma.f64(double, double, double, metadata, metadata)
435 declare double @llvm.experimental.constrained.fmuladd.f64(double, double, double, metadata, metadata)