diff options
Diffstat (limited to 'llvm/test')
-rw-r--r-- | llvm/test/CodeGen/X86/fp-intrinsics.ll | 111 | ||||
-rw-r--r-- | llvm/test/Feature/fp-intrinsics.ll | 102 | ||||
-rw-r--r-- | llvm/test/Verifier/fp-intrinsics.ll | 43 |
3 files changed, 256 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/X86/fp-intrinsics.ll b/llvm/test/CodeGen/X86/fp-intrinsics.ll new file mode 100644 index 00000000000..88aef6bb065 --- /dev/null +++ b/llvm/test/CodeGen/X86/fp-intrinsics.ll @@ -0,0 +1,111 @@ +; RUN: llc -O3 -mtriple=x86_64-pc-linux < %s | FileCheck %s + +; Verify that constants aren't folded to inexact results when the rounding mode +; is unknown. +; +; double f1() { +; // Because 0.1 cannot be represented exactly, this shouldn't be folded. +; return 1.0/10.0; +; } +; +; CHECK-LABEL: f1 +; CHECK: divsd +define double @f1() { +entry: + %div = call double @llvm.experimental.constrained.fdiv.f64( + double 1.000000e+00, + double 1.000000e+01, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret double %div +} + +; Verify that 'a - 0' isn't simplified to 'a' when the rounding mode is unknown. +; +; double f2(double a) { +; // Because the result of '0 - 0' is negative zero if rounding mode is +; // downward, this shouldn't be simplified. +; return a - 0; +; } +; +; CHECK-LABEL: f2 +; CHECK: subsd +define double @f2(double %a) { +entry: + %div = call double @llvm.experimental.constrained.fsub.f64( + double %a, + double 0.000000e+00, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret double %div +} + +; Verify that '-((-a)*b)' isn't simplified to 'a*b' when the rounding mode is +; unknown. +; +; double f3(double a, double b) { +; // Because the intermediate value involved in this calculation may require +; // rounding, this shouldn't be simplified. +; return -((-a)*b); +; } +; +; CHECK-LABEL: f3: +; CHECK: subsd +; CHECK: mulsd +; CHECK: subsd +define double @f3(double %a, double %b) { +entry: + %sub = call double @llvm.experimental.constrained.fsub.f64( + double -0.000000e+00, double %a, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + %mul = call double @llvm.experimental.constrained.fmul.f64( + double %sub, double %b, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + %ret = call double @llvm.experimental.constrained.fsub.f64( + double -0.000000e+00, + double %mul, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret double %ret +} + +; Verify that FP operations are not performed speculatively when FP exceptions +; are not being ignored. +; +; double f4(int n, double a) { +; // Because a + 1 may overflow, this should not be simplified. +; if (n > 0) +; return a + 1.0; +; return a; +; } +; +; +; CHECK-LABEL: f4: +; CHECK: testl +; CHECK: jle +; CHECK: addsd +define double @f4(i32 %n, double %a) { +entry: + %cmp = icmp sgt i32 %n, 0 + br i1 %cmp, label %if.then, label %if.end + +if.then: + %add = call double @llvm.experimental.constrained.fadd.f64( + double 1.000000e+00, double %a, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + br label %if.end + +if.end: + %a.0 = phi double [%add, %if.then], [ %a, %entry ] + ret double %a.0 +} + + +@llvm.fp.env = thread_local global i8 zeroinitializer, section "llvm.metadata" +declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata) +declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata) +declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata) +declare double @llvm.experimental.constrained.fsub.f64(double, double, metadata, metadata) diff --git a/llvm/test/Feature/fp-intrinsics.ll b/llvm/test/Feature/fp-intrinsics.ll new file mode 100644 index 00000000000..960bfb5ca10 --- /dev/null +++ b/llvm/test/Feature/fp-intrinsics.ll @@ -0,0 +1,102 @@ +; RUN: opt -O3 -S < %s | FileCheck %s + +; Test to verify that constants aren't folded when the rounding mode is unknown. +; CHECK-LABEL: @f1 +; CHECK: call double @llvm.experimental.constrained.fdiv.f64 +define double @f1() { +entry: + %div = call double @llvm.experimental.constrained.fdiv.f64( + double 1.000000e+00, + double 1.000000e+01, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret double %div +} + +; Verify that 'a - 0' isn't simplified to 'a' when the rounding mode is unknown. +; +; double f2(double a) { +; // Because the result of '0 - 0' is negative zero if rounding mode is +; // downward, this shouldn't be simplified. +; return a - 0.0; +; } +; +; CHECK-LABEL: @f2 +; CHECK: call double @llvm.experimental.constrained.fsub.f64 +define double @f2(double %a) { +entry: + %div = call double @llvm.experimental.constrained.fsub.f64( + double %a, double 0.000000e+00, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret double %div +} + +; Verify that '-((-a)*b)' isn't simplified to 'a*b' when the rounding mode is +; unknown. +; +; double f3(double a, double b) { +; // Because the intermediate value involved in this calculation may require +; // rounding, this shouldn't be simplified. +; return -((-a)*b); +; } +; +; CHECK-LABEL: @f3 +; CHECK: call double @llvm.experimental.constrained.fsub.f64 +; CHECK: call double @llvm.experimental.constrained.fmul.f64 +; CHECK: call double @llvm.experimental.constrained.fsub.f64 +define double @f3(double %a, double %b) { +entry: + %sub = call double @llvm.experimental.constrained.fsub.f64( + double -0.000000e+00, double %a, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + %mul = call double @llvm.experimental.constrained.fmul.f64( + double %sub, double %b, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + %ret = call double @llvm.experimental.constrained.fsub.f64( + double -0.000000e+00, + double %mul, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret double %ret +} + +; Verify that FP operations are not performed speculatively when FP exceptions +; are not being ignored. +; +; double f4(int n, double a) { +; // Because a + 1 may overflow, this should not be simplified. +; if (n > 0) +; return a + 1.0; +; return a; +; } +; +; +; CHECK-LABEL: @f4 +; CHECK-NOT: select +; CHECK: br i1 %cmp +define double @f4(i32 %n, double %a) { +entry: + %cmp = icmp sgt i32 %n, 0 + br i1 %cmp, label %if.then, label %if.end + +if.then: + %add = call double @llvm.experimental.constrained.fadd.f64( + double 1.000000e+00, double %a, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + br label %if.end + +if.end: + %a.0 = phi double [%add, %if.then], [ %a, %entry ] + ret double %a.0 +} + + +@llvm.fp.env = thread_local global i8 zeroinitializer, section "llvm.metadata" +declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata) +declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata) +declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata) +declare double @llvm.experimental.constrained.fsub.f64(double, double, metadata, metadata) diff --git a/llvm/test/Verifier/fp-intrinsics.ll b/llvm/test/Verifier/fp-intrinsics.ll new file mode 100644 index 00000000000..0a308115cc3 --- /dev/null +++ b/llvm/test/Verifier/fp-intrinsics.ll @@ -0,0 +1,43 @@ +; RUN: opt -verify -S < %s 2>&1 | FileCheck --check-prefix=CHECK1 %s +; RUN: sed -e s/.T2:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK2 %s +; RUN: sed -e s/.T3:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK3 %s + +; Common declaration used for all runs. +declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata) + +; Test that the verifier accepts legal code, and that the correct attributes are +; attached to the FP intrinsic. +; CHECK1: declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata) #[[ATTR:[0-9]+]] +; CHECK1: attributes #[[ATTR]] = { inaccessiblememonly nounwind } +; Note: FP exceptions aren't usually caught through normal unwind mechanisms, +; but we may want to revisit this for asynchronous exception handling. +define double @f1(double %a, double %b) { +entry: + %fadd = call double @llvm.experimental.constrained.fadd.f64( + double %a, double %b, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret double %fadd +} + +; Test an illegal value for the rounding mode argument. +; CHECK2: invalid rounding mode argument +;T2: define double @f2(double %a, double %b) { +;T2: entry: +;T2: %fadd = call double @llvm.experimental.constrained.fadd.f64( +;T2: double %a, double %b, +;T2: metadata !"round.dynomite", +;T2: metadata !"fpexcept.strict") +;T2: ret double %fadd +;T2: } + +; Test an illegal value for the exception behavior argument. +; CHECK3: invalid exception behavior argument +;T3: define double @f2(double %a, double %b) { +;T3: entry: +;T3: %fadd = call double @llvm.experimental.constrained.fadd.f64( +;T3: double %a, double %b, +;T3: metadata !"round.dynamic", +;T3: metadata !"fpexcept.restrict") +;T3: ret double %fadd +;T3: } |