aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Voung <jvoung@chromium.org>2013-07-02 16:29:16 -0700
committerJan Voung <jvoung@chromium.org>2013-07-02 16:29:16 -0700
commita6817fbfe9248e8992132206448eb5eda1745c92 (patch)
tree3b25adc633ea5203d5f52b028e67692a8858fb39
parent66d0d318bec6819fee76f501e67c674cf7a112d0 (diff)
Move LLVM sqrt intrinsic to stable (for float and doubles).
On the hardware that we support, they are implemented by instructions and have consistent behavior for -0.0, values less than -0.0, infinity, and nan. We will need to be careful to guarantee the same behavior for untested hardware. TEST=run_llvm_math_intrinsics_test BUG=http://code.google.com/p/nativeclient/issues/detail?id=3378 R=jfb@chromium.org, mseaborn@chromium.org Review URL: https://codereview.chromium.org/18559005
-rw-r--r--docs/PNaClLangRef.rst6
-rw-r--r--lib/Analysis/NaCl/PNaClABIVerifyModule.cpp7
-rw-r--r--test/NaCl/PNaClABI/intrinsics.ll6
3 files changed, 18 insertions, 1 deletions
diff --git a/docs/PNaClLangRef.rst b/docs/PNaClLangRef.rst
index e48bebc84d..4f322a3eff 100644
--- a/docs/PNaClLangRef.rst
+++ b/docs/PNaClLangRef.rst
@@ -344,6 +344,12 @@ TODO(jfb): atomics
supported with the i32 and i64 argument types (the types supported by
C-style GCC builtins).
+* ``llvm.sqrt``
+
+ The overloaded ``llvm.sqrt`` intrinsic is only supported for float
+ and double arguments types. Unlike the standard LLVM intrinsic,
+ PNaCl guarantees that llvm.sqrt returns a QNaN for values less than -0.0.
+
* ``llvm.stacksave``
* ``llvm.stackrestore``
* ``llvm.trap``
diff --git a/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp b/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp
index 8bf0848fd7..890bb907b8 100644
--- a/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp
+++ b/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp
@@ -176,6 +176,8 @@ AllowedIntrinsics::AllowedIntrinsics(LLVMContext *Context) : Context(Context) {
Type *I16 = Type::getInt16Ty(*Context);
Type *I32 = Type::getInt32Ty(*Context);
Type *I64 = Type::getInt64Ty(*Context);
+ Type *Float = Type::getFloatTy(*Context);
+ Type *Double = Type::getDoubleTy(*Context);
// We accept bswap for a limited set of types (i16, i32, i64). The
// various backends are able to generate instructions to implement
@@ -197,6 +199,10 @@ AllowedIntrinsics::AllowedIntrinsics(LLVMContext *Context) : Context(Context) {
addIntrinsic(Intrinsic::nacl_longjmp);
addIntrinsic(Intrinsic::nacl_setjmp);
+ // For native sqrt instructions. Must guarantee when x < -0.0, sqrt(x) = NaN.
+ addIntrinsic(Intrinsic::sqrt, Float);
+ addIntrinsic(Intrinsic::sqrt, Double);
+
// Stack save and restore are used to support C99 VLAs.
addIntrinsic(Intrinsic::stacksave);
addIntrinsic(Intrinsic::stackrestore);
@@ -299,7 +305,6 @@ bool AllowedIntrinsics::isAllowed(const Function *Func) {
case Intrinsic::nacl_target_arch: // Used by translator self-build.
case Intrinsic::powi: // Rounding not defined: support with fast-math?
case Intrinsic::prefetch: // TODO(jfb): Use our own data-prefetch intrinsic instead.
- case Intrinsic::sqrt: // Rounding is defined, but setting errno up to libm.
return PNaClABIAllowDevIntrinsics;
}
}
diff --git a/test/NaCl/PNaClABI/intrinsics.ll b/test/NaCl/PNaClABI/intrinsics.ll
index 1c28cfd967..7c5e76e795 100644
--- a/test/NaCl/PNaClABI/intrinsics.ll
+++ b/test/NaCl/PNaClABI/intrinsics.ll
@@ -40,6 +40,9 @@ declare i64 @llvm.ctpop.i64(i64)
declare void @llvm.trap()
+declare float @llvm.sqrt.f32(float)
+declare double @llvm.sqrt.f64(double)
+
declare i8* @llvm.stacksave()
declare void @llvm.stackrestore(i8*)
@@ -98,6 +101,9 @@ declare i8* @llvm.frameaddress(i32 %level)
; CHECK: Function llvm.returnaddress is a disallowed LLVM intrinsic
declare i8* @llvm.returnaddress(i32 %level)
+; CHECK: Function llvm.sqrt.fp128 is a disallowed LLVM intrinsic
+declare fp128 @llvm.sqrt.fp128(fp128)
+
; The variants with 64-bit %len arguments are disallowed.
; CHECK: Function llvm.memcpy.p0i8.p0i8.i64 is a disallowed LLVM intrinsic
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* %dest, i8* %src,