diff options
author | Jan Voung <jvoung@chromium.org> | 2013-07-02 16:29:16 -0700 |
---|---|---|
committer | Jan Voung <jvoung@chromium.org> | 2013-07-02 16:29:16 -0700 |
commit | a6817fbfe9248e8992132206448eb5eda1745c92 (patch) | |
tree | 3b25adc633ea5203d5f52b028e67692a8858fb39 | |
parent | 66d0d318bec6819fee76f501e67c674cf7a112d0 (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.rst | 6 | ||||
-rw-r--r-- | lib/Analysis/NaCl/PNaClABIVerifyModule.cpp | 7 | ||||
-rw-r--r-- | test/NaCl/PNaClABI/intrinsics.ll | 6 |
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, |