[InstCombine] Signed saturation patterns
[llvm-core.git] / test / CodeGen / X86 / fp-intrinsics.ll
blob2f5224eaf6c2fe3f69aa39d043274ca9d4971be0
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
5 ; is unknown.
7 ; double f1() {
8 ;   // Because 0.1 cannot be represented exactly, this shouldn't be folded.
9 ;   return 1.0/10.0;
10 ; }
12 ; CHECK-LABEL: f1
13 ; COMMON: divsd
14 define double @f1() #0 {
15 entry:
16   %div = call double @llvm.experimental.constrained.fdiv.f64(
17                                                double 1.000000e+00,
18                                                double 1.000000e+01,
19                                                metadata !"round.dynamic",
20                                                metadata !"fpexcept.strict") #0
21   ret double %div
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.
29 ;   return a - 0;
30 ; }
32 ; CHECK-LABEL: f2
33 ; COMMON:  subsd
34 define double @f2(double %a) #0 {
35 entry:
36   %sub = call double @llvm.experimental.constrained.fsub.f64(
37                                                double %a,
38                                                double 0.000000e+00,
39                                                metadata !"round.dynamic",
40                                                metadata !"fpexcept.strict") #0
41   ret double %sub
44 ; Verify that '-((-a)*b)' isn't simplified to 'a*b' when the rounding mode is
45 ; unknown.
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.
50 ;   return -((-a)*b);
51 ; }
53 ; CHECK-LABEL: f3:
54 ; COMMON:  subsd
55 ; COMMON:  mulsd
56 ; COMMON:  subsd
57 define double @f3(double %a, double %b) #0 {
58 entry:
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(
68                                                double -0.000000e+00,
69                                                double %mul,
70                                                metadata !"round.dynamic",
71                                                metadata !"fpexcept.strict") #0
72   ret double %ret
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.
80 ;   if (n > 0)
81 ;     return a + 1.0;
82 ;   return a;
83 ; }
86 ; CHECK-LABEL: f4:
87 ; COMMON: testl
88 ; COMMON: jle
89 ; COMMON: addsd
90 define double @f4(i32 %n, double %a) #0 {
91 entry:
92   %cmp = icmp sgt i32 %n, 0
93   br i1 %cmp, label %if.then, label %if.end
95 if.then:
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
100   br label %if.end
102 if.end:
103   %a.0 = phi double [%add, %if.then], [ %a, %entry ]
104   ret double %a.0
107 ; Verify that sqrt(42.0) isn't simplified when the rounding mode is unknown.
108 ; CHECK-LABEL: f5
109 ; COMMON:  sqrtsd
110 define double @f5() #0 {
111 entry:
112   %result = call double @llvm.experimental.constrained.sqrt.f64(double 42.0,
113                                                metadata !"round.dynamic",
114                                                metadata !"fpexcept.strict") #0
115   ret double %result
118 ; Verify that pow(42.1, 3.0) isn't simplified when the rounding mode is unknown.
119 ; CHECK-LABEL: f6
120 ; COMMON:  pow
121 define double @f6() #0 {
122 entry:
123   %result = call double @llvm.experimental.constrained.pow.f64(double 42.1,
124                                                double 3.0,
125                                                metadata !"round.dynamic",
126                                                metadata !"fpexcept.strict") #0
127   ret double %result
130 ; Verify that powi(42.1, 3) isn't simplified when the rounding mode is unknown.
131 ; CHECK-LABEL: f7
132 ; COMMON:  powi
133 define double @f7() #0 {
134 entry:
135   %result = call double @llvm.experimental.constrained.powi.f64(double 42.1,
136                                                i32 3,
137                                                metadata !"round.dynamic",
138                                                metadata !"fpexcept.strict") #0
139   ret double %result
142 ; Verify that sin(42.0) isn't simplified when the rounding mode is unknown.
143 ; CHECK-LABEL: f8
144 ; COMMON:  sin
145 define double @f8() #0 {
146 entry:
147   %result = call double @llvm.experimental.constrained.sin.f64(double 42.0,
148                                                metadata !"round.dynamic",
149                                                metadata !"fpexcept.strict") #0
150   ret double %result
153 ; Verify that cos(42.0) isn't simplified when the rounding mode is unknown.
154 ; CHECK-LABEL: f9
155 ; COMMON:  cos
156 define double @f9() #0 {
157 entry:
158   %result = call double @llvm.experimental.constrained.cos.f64(double 42.0,
159                                                metadata !"round.dynamic",
160                                                metadata !"fpexcept.strict") #0
161   ret double %result
164 ; Verify that exp(42.0) isn't simplified when the rounding mode is unknown.
165 ; CHECK-LABEL: f10
166 ; COMMON:  exp
167 define double @f10() #0 {
168 entry:
169   %result = call double @llvm.experimental.constrained.exp.f64(double 42.0,
170                                                metadata !"round.dynamic",
171                                                metadata !"fpexcept.strict") #0
172   ret double %result
175 ; Verify that exp2(42.1) isn't simplified when the rounding mode is unknown.
176 ; CHECK-LABEL: f11
177 ; COMMON:  exp2
178 define double @f11() #0 {
179 entry:
180   %result = call double @llvm.experimental.constrained.exp2.f64(double 42.1,
181                                                metadata !"round.dynamic",
182                                                metadata !"fpexcept.strict") #0
183   ret double %result
186 ; Verify that log(42.0) isn't simplified when the rounding mode is unknown.
187 ; CHECK-LABEL: f12
188 ; COMMON:  log
189 define double @f12() #0 {
190 entry:
191   %result = call double @llvm.experimental.constrained.log.f64(double 42.0,
192                                                metadata !"round.dynamic",
193                                                metadata !"fpexcept.strict") #0
194   ret double %result
197 ; Verify that log10(42.0) isn't simplified when the rounding mode is unknown.
198 ; CHECK-LABEL: f13
199 ; COMMON:  log10
200 define double @f13() #0 {
201 entry:
202   %result = call double @llvm.experimental.constrained.log10.f64(double 42.0,
203                                                metadata !"round.dynamic",
204                                                metadata !"fpexcept.strict") #0
205   ret double %result
208 ; Verify that log2(42.0) isn't simplified when the rounding mode is unknown.
209 ; CHECK-LABEL: f14
210 ; COMMON:  log2
211 define double @f14() #0 {
212 entry:
213   %result = call double @llvm.experimental.constrained.log2.f64(double 42.0,
214                                                metadata !"round.dynamic",
215                                                metadata !"fpexcept.strict") #0
216   ret double %result
219 ; Verify that rint(42.1) isn't simplified when the rounding mode is unknown.
220 ; CHECK-LABEL: f15
221 ; NO-FMA:  rint
222 ; HAS-FMA: vroundsd
223 define double @f15() #0 {
224 entry:
225   %result = call double @llvm.experimental.constrained.rint.f64(double 42.1,
226                                                metadata !"round.dynamic",
227                                                metadata !"fpexcept.strict") #0
228   ret double %result
231 ; Verify that nearbyint(42.1) isn't simplified when the rounding mode is
232 ; unknown.
233 ; CHECK-LABEL: f16
234 ; NO-FMA:  nearbyint
235 ; HAS-FMA: vroundsd
236 define double @f16() #0 {
237 entry:
238   %result = call double @llvm.experimental.constrained.nearbyint.f64(
239                                                double 42.1,
240                                                metadata !"round.dynamic",
241                                                metadata !"fpexcept.strict") #0
242   ret double %result
245 ; Verify that fma(3.5) isn't simplified when the rounding mode is
246 ; unknown.
247 ; CHECK-LABEL: f17
248 ; FMACALL32: jmp fmaf  # TAILCALL
249 ; FMA32: vfmadd213ss
250 define float @f17() #0 {
251 entry:
252   %result = call float @llvm.experimental.constrained.fma.f32(
253                                                float 3.5,
254                                                float 3.5,
255                                                float 3.5,
256                                                metadata !"round.dynamic",
257                                                metadata !"fpexcept.strict") #0
258   ret float %result
261 ; Verify that fma(42.1) isn't simplified when the rounding mode is
262 ; unknown.
263 ; CHECK-LABEL: f18
264 ; FMACALL64: jmp fma  # TAILCALL
265 ; FMA64: vfmadd213sd
266 define double @f18() #0 {
267 entry:
268   %result = call double @llvm.experimental.constrained.fma.f64(
269                                                double 42.1,
270                                                double 42.1,
271                                                double 42.1,
272                                                metadata !"round.dynamic",
273                                                metadata !"fpexcept.strict") #0
274   ret double %result
277 ; CHECK-LABEL: f19
278 ; COMMON: fmod
279 define double @f19() #0 {
280 entry:
281   %rem = call double @llvm.experimental.constrained.frem.f64(
282                                                double 1.000000e+00,
283                                                double 1.000000e+01,
284                                                metadata !"round.dynamic",
285                                                metadata !"fpexcept.strict") #0
286   ret double %rem
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.
292 ; CHECK-LABEL: @f20u
293 ; NO-FMA: cmpltsd
294 ; NO-FMA: movapd
295 ; NO-FMA: andpd
296 ; NO-FMA: xorl
297 ; NO-FMA: ucomisd
298 ; NO-FMA: subsd
299 ; NO-FMA: andnpd
300 ; NO-FMA: orpd
301 ; NO-FMA: cvttsd2si
302 ; NO-FMA: setae
303 ; NO-FMA: shll
304 ; NO-FMA: xorl
306 ; HAS-FMA: vcmpltsd
307 ; HAS-FMA: vsubsd
308 ; HAS-FMA: vblendvpd
309 ; HAS-FMA: vcvttsd2si
310 ; HAS-FMA: xorl
311 ; HAS-FMA: vucomisd
312 ; HAS-FMA: setae
313 ; HAS-FMA: shll
314 ; HAS-FMA: xorl
315 define i32 @f20u(double %x) #0 {
316 entry:
317   %result = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double %x,
318                                                metadata !"fpexcept.strict") #0
319   ret i32 %result
322 ; Verify that round(42.1) isn't simplified when the rounding mode is
323 ; unknown.
324 ; Verify that no gross errors happen.
325 ; CHECK-LABEL: @f21
326 ; COMMON: cvtsd2ss
327 define float @f21() #0 {
328 entry:
329   %result = call float @llvm.experimental.constrained.fptrunc.f32.f64(
330                                                double 42.1,
331                                                metadata !"round.dynamic",
332                                                metadata !"fpexcept.strict") #0
333   ret float %result
336 ; CHECK-LABEL: @f22
337 ; COMMON: cvtss2sd
338 define double @f22(float %x) #0 {
339 entry:
340   %result = call double @llvm.experimental.constrained.fpext.f64.f32(float %x,
341                                                metadata !"fpexcept.strict") #0
342   ret double %result
345 ; CHECK-LABEL: f23
346 ; COMMON: jmp lrint
347 define i32 @f23(double %x) #0 {
348 entry:
349   %result = call i32 @llvm.experimental.constrained.lrint.i32.f64(double %x,
350                                                metadata !"round.dynamic",
351                                                metadata !"fpexcept.strict") #0
352   ret i32 %result
355 ; CHECK-LABEL: f24
356 ; COMMON: jmp lrintf
357 define i32 @f24(float %x) #0 {
358 entry:
359   %result = call i32 @llvm.experimental.constrained.lrint.i32.f32(float %x,
360                                                metadata !"round.dynamic",
361                                                metadata !"fpexcept.strict") #0
362   ret i32 %result
365 ; CHECK-LABEL: f25
366 ; COMMON: jmp llrint
367 define i64 @f25(double %x) #0 {
368 entry:
369   %result = call i64 @llvm.experimental.constrained.llrint.i64.f64(double %x,
370                                                metadata !"round.dynamic",
371                                                metadata !"fpexcept.strict") #0
372   ret i64 %result
375 ; CHECK-LABEL: f26
376 ; COMMON: jmp llrintf
377 define i64 @f26(float %x) {
378 entry:
379   %result = call i64 @llvm.experimental.constrained.llrint.i64.f32(float %x,
380                                                metadata !"round.dynamic",
381                                                metadata !"fpexcept.strict") #0
382   ret i64 %result
385 ; CHECK-LABEL: f27
386 ; COMMON: jmp lround
387 define i32 @f27(double %x) #0 {
388 entry:
389   %result = call i32 @llvm.experimental.constrained.lround.i32.f64(double %x,
390                                                metadata !"fpexcept.strict") #0
391   ret i32 %result
394 ; CHECK-LABEL: f28
395 ; COMMON: jmp lroundf
396 define i32 @f28(float %x) #0 {
397 entry:
398   %result = call i32 @llvm.experimental.constrained.lround.i32.f32(float %x,
399                                                metadata !"fpexcept.strict") #0
400   ret i32 %result
403 ; CHECK-LABEL: f29
404 ; COMMON: jmp llround
405 define i64 @f29(double %x) #0 {
406 entry:
407   %result = call i64 @llvm.experimental.constrained.llround.i64.f64(double %x,
408                                                metadata !"fpexcept.strict") #0
409   ret i64 %result
412 ; CHECK-LABEL: f30
413 ; COMMON: jmp llroundf
414 define i64 @f30(float %x) #0 {
415 entry:
416   %result = call i64 @llvm.experimental.constrained.llround.i64.f32(float %x,
417                                                metadata !"fpexcept.strict") #0
418   ret i64 %result
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)