1 ; RUN: llc -O3 -mtriple=x86_64-pc-linux < %s | FileCheck --check-prefix=COMMON --check-prefix=NO-FMA --check-prefix=FMACALL64 --check-prefix=FMACALL32 %s
2 ; RUN: llc -O3 -mtriple=x86_64-pc-linux -mattr=+fma < %s | FileCheck -check-prefix=COMMON --check-prefix=HAS-FMA --check-prefix=FMA64 --check-prefix=FMA32 %s
4 ; Verify that constants aren't folded to inexact results when the rounding mode
8 ; // Because 0.1 cannot be represented exactly, this shouldn't be folded.
14 define double @f1() #0 {
16 %div = call double @llvm.experimental.constrained.fdiv.f64(
19 metadata !"round.dynamic",
20 metadata !"fpexcept.strict") #0
24 ; Verify that 'a - 0' isn't simplified to 'a' when the rounding mode is unknown.
26 ; double f2(double a) {
27 ; // Because the result of '0 - 0' is negative zero if rounding mode is
28 ; // downward, this shouldn't be simplified.
34 define double @f2(double %a) #0 {
36 %sub = call double @llvm.experimental.constrained.fsub.f64(
39 metadata !"round.dynamic",
40 metadata !"fpexcept.strict") #0
44 ; Verify that '-((-a)*b)' isn't simplified to 'a*b' when the rounding mode is
47 ; double f3(double a, double b) {
48 ; // Because the intermediate value involved in this calculation may require
49 ; // rounding, this shouldn't be simplified.
57 define double @f3(double %a, double %b) #0 {
59 %sub = call double @llvm.experimental.constrained.fsub.f64(
60 double -0.000000e+00, double %a,
61 metadata !"round.dynamic",
62 metadata !"fpexcept.strict") #0
63 %mul = call double @llvm.experimental.constrained.fmul.f64(
64 double %sub, double %b,
65 metadata !"round.dynamic",
66 metadata !"fpexcept.strict") #0
67 %ret = call double @llvm.experimental.constrained.fsub.f64(
70 metadata !"round.dynamic",
71 metadata !"fpexcept.strict") #0
75 ; Verify that FP operations are not performed speculatively when FP exceptions
76 ; are not being ignored.
78 ; double f4(int n, double a) {
79 ; // Because a + 1 may overflow, this should not be simplified.
90 define double @f4(i32 %n, double %a) #0 {
92 %cmp = icmp sgt i32 %n, 0
93 br i1 %cmp, label %if.then, label %if.end
96 %add = call double @llvm.experimental.constrained.fadd.f64(
97 double 1.000000e+00, double %a,
98 metadata !"round.dynamic",
99 metadata !"fpexcept.strict") #0
103 %a.0 = phi double [%add, %if.then], [ %a, %entry ]
107 ; Verify that sqrt(42.0) isn't simplified when the rounding mode is unknown.
110 define double @f5() #0 {
112 %result = call double @llvm.experimental.constrained.sqrt.f64(double 42.0,
113 metadata !"round.dynamic",
114 metadata !"fpexcept.strict") #0
118 ; Verify that pow(42.1, 3.0) isn't simplified when the rounding mode is unknown.
121 define double @f6() #0 {
123 %result = call double @llvm.experimental.constrained.pow.f64(double 42.1,
125 metadata !"round.dynamic",
126 metadata !"fpexcept.strict") #0
130 ; Verify that powi(42.1, 3) isn't simplified when the rounding mode is unknown.
133 define double @f7() #0 {
135 %result = call double @llvm.experimental.constrained.powi.f64(double 42.1,
137 metadata !"round.dynamic",
138 metadata !"fpexcept.strict") #0
142 ; Verify that sin(42.0) isn't simplified when the rounding mode is unknown.
145 define double @f8() #0 {
147 %result = call double @llvm.experimental.constrained.sin.f64(double 42.0,
148 metadata !"round.dynamic",
149 metadata !"fpexcept.strict") #0
153 ; Verify that cos(42.0) isn't simplified when the rounding mode is unknown.
156 define double @f9() #0 {
158 %result = call double @llvm.experimental.constrained.cos.f64(double 42.0,
159 metadata !"round.dynamic",
160 metadata !"fpexcept.strict") #0
164 ; Verify that exp(42.0) isn't simplified when the rounding mode is unknown.
167 define double @f10() #0 {
169 %result = call double @llvm.experimental.constrained.exp.f64(double 42.0,
170 metadata !"round.dynamic",
171 metadata !"fpexcept.strict") #0
175 ; Verify that exp2(42.1) isn't simplified when the rounding mode is unknown.
178 define double @f11() #0 {
180 %result = call double @llvm.experimental.constrained.exp2.f64(double 42.1,
181 metadata !"round.dynamic",
182 metadata !"fpexcept.strict") #0
186 ; Verify that log(42.0) isn't simplified when the rounding mode is unknown.
189 define double @f12() #0 {
191 %result = call double @llvm.experimental.constrained.log.f64(double 42.0,
192 metadata !"round.dynamic",
193 metadata !"fpexcept.strict") #0
197 ; Verify that log10(42.0) isn't simplified when the rounding mode is unknown.
200 define double @f13() #0 {
202 %result = call double @llvm.experimental.constrained.log10.f64(double 42.0,
203 metadata !"round.dynamic",
204 metadata !"fpexcept.strict") #0
208 ; Verify that log2(42.0) isn't simplified when the rounding mode is unknown.
211 define double @f14() #0 {
213 %result = call double @llvm.experimental.constrained.log2.f64(double 42.0,
214 metadata !"round.dynamic",
215 metadata !"fpexcept.strict") #0
219 ; Verify that rint(42.1) isn't simplified when the rounding mode is unknown.
223 define double @f15() #0 {
225 %result = call double @llvm.experimental.constrained.rint.f64(double 42.1,
226 metadata !"round.dynamic",
227 metadata !"fpexcept.strict") #0
231 ; Verify that nearbyint(42.1) isn't simplified when the rounding mode is
236 define double @f16() #0 {
238 %result = call double @llvm.experimental.constrained.nearbyint.f64(
240 metadata !"round.dynamic",
241 metadata !"fpexcept.strict") #0
245 ; Verify that fma(3.5) isn't simplified when the rounding mode is
248 ; FMACALL32: jmp fmaf # TAILCALL
250 define float @f17() #0 {
252 %result = call float @llvm.experimental.constrained.fma.f32(
256 metadata !"round.dynamic",
257 metadata !"fpexcept.strict") #0
261 ; Verify that fma(42.1) isn't simplified when the rounding mode is
264 ; FMACALL64: jmp fma # TAILCALL
266 define double @f18() #0 {
268 %result = call double @llvm.experimental.constrained.fma.f64(
272 metadata !"round.dynamic",
273 metadata !"fpexcept.strict") #0
279 define double @f19() #0 {
281 %rem = call double @llvm.experimental.constrained.frem.f64(
284 metadata !"round.dynamic",
285 metadata !"fpexcept.strict") #0
289 ; Verify that fptoui(%x) isn't simplified when the rounding mode is
290 ; unknown. The expansion should have only one conversion instruction.
291 ; Verify that no gross errors happen.
309 ; HAS-FMA: vcvttsd2si
315 define i32 @f20u(double %x) #0 {
317 %result = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double %x,
318 metadata !"fpexcept.strict") #0
322 ; Verify that round(42.1) isn't simplified when the rounding mode is
324 ; Verify that no gross errors happen.
327 define float @f21() #0 {
329 %result = call float @llvm.experimental.constrained.fptrunc.f32.f64(
331 metadata !"round.dynamic",
332 metadata !"fpexcept.strict") #0
338 define double @f22(float %x) #0 {
340 %result = call double @llvm.experimental.constrained.fpext.f64.f32(float %x,
341 metadata !"fpexcept.strict") #0
347 define i32 @f23(double %x) #0 {
349 %result = call i32 @llvm.experimental.constrained.lrint.i32.f64(double %x,
350 metadata !"round.dynamic",
351 metadata !"fpexcept.strict") #0
357 define i32 @f24(float %x) #0 {
359 %result = call i32 @llvm.experimental.constrained.lrint.i32.f32(float %x,
360 metadata !"round.dynamic",
361 metadata !"fpexcept.strict") #0
367 define i64 @f25(double %x) #0 {
369 %result = call i64 @llvm.experimental.constrained.llrint.i64.f64(double %x,
370 metadata !"round.dynamic",
371 metadata !"fpexcept.strict") #0
376 ; COMMON: jmp llrintf
377 define i64 @f26(float %x) {
379 %result = call i64 @llvm.experimental.constrained.llrint.i64.f32(float %x,
380 metadata !"round.dynamic",
381 metadata !"fpexcept.strict") #0
387 define i32 @f27(double %x) #0 {
389 %result = call i32 @llvm.experimental.constrained.lround.i32.f64(double %x,
390 metadata !"fpexcept.strict") #0
395 ; COMMON: jmp lroundf
396 define i32 @f28(float %x) #0 {
398 %result = call i32 @llvm.experimental.constrained.lround.i32.f32(float %x,
399 metadata !"fpexcept.strict") #0
404 ; COMMON: jmp llround
405 define i64 @f29(double %x) #0 {
407 %result = call i64 @llvm.experimental.constrained.llround.i64.f64(double %x,
408 metadata !"fpexcept.strict") #0
413 ; COMMON: jmp llroundf
414 define i64 @f30(float %x) #0 {
416 %result = call i64 @llvm.experimental.constrained.llround.i64.f32(float %x,
417 metadata !"fpexcept.strict") #0
421 attributes #0 = { strictfp }
423 @llvm.fp.env = thread_local global i8 zeroinitializer, section "llvm.metadata"
424 declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata)
425 declare double @llvm.experimental.constrained.fsub.f64(double, double, metadata, metadata)
426 declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata)
427 declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata)
428 declare double @llvm.experimental.constrained.frem.f64(double, double, metadata, metadata)
429 declare double @llvm.experimental.constrained.sqrt.f64(double, metadata, metadata)
430 declare double @llvm.experimental.constrained.pow.f64(double, double, metadata, metadata)
431 declare double @llvm.experimental.constrained.powi.f64(double, i32, metadata, metadata)
432 declare double @llvm.experimental.constrained.sin.f64(double, metadata, metadata)
433 declare double @llvm.experimental.constrained.cos.f64(double, metadata, metadata)
434 declare double @llvm.experimental.constrained.exp.f64(double, metadata, metadata)
435 declare double @llvm.experimental.constrained.exp2.f64(double, metadata, metadata)
436 declare double @llvm.experimental.constrained.log.f64(double, metadata, metadata)
437 declare double @llvm.experimental.constrained.log10.f64(double, metadata, metadata)
438 declare double @llvm.experimental.constrained.log2.f64(double, metadata, metadata)
439 declare double @llvm.experimental.constrained.rint.f64(double, metadata, metadata)
440 declare double @llvm.experimental.constrained.nearbyint.f64(double, metadata, metadata)
441 declare float @llvm.experimental.constrained.fma.f32(float, float, float, metadata, metadata)
442 declare double @llvm.experimental.constrained.fma.f64(double, double, double, metadata, metadata)
443 declare i32 @llvm.experimental.constrained.fptosi.i32.f64(double, metadata)
444 declare i32 @llvm.experimental.constrained.fptoui.i32.f64(double, metadata)
445 declare float @llvm.experimental.constrained.fptrunc.f32.f64(double, metadata, metadata)
446 declare double @llvm.experimental.constrained.fpext.f64.f32(float, metadata)
447 declare i32 @llvm.experimental.constrained.lrint.i32.f64(double, metadata, metadata)
448 declare i32 @llvm.experimental.constrained.lrint.i32.f32(float, metadata, metadata)
449 declare i64 @llvm.experimental.constrained.llrint.i64.f64(double, metadata, metadata)
450 declare i64 @llvm.experimental.constrained.llrint.i64.f32(float, metadata, metadata)
451 declare i32 @llvm.experimental.constrained.lround.i32.f64(double, metadata)
452 declare i32 @llvm.experimental.constrained.lround.i32.f32(float, metadata)
453 declare i64 @llvm.experimental.constrained.llround.i64.f64(double, metadata)
454 declare i64 @llvm.experimental.constrained.llround.i64.f32(float, metadata)