diff options
author | Sanjay Patel <spatel@rotateright.com> | 2017-10-31 20:19:39 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2017-10-31 20:19:39 +0000 |
commit | 7cb25a888ce53c288de9369c5b98082b4ea5ec26 (patch) | |
tree | 298d75644c31f5c8a0594f00cb3936d876eb2413 /clang/lib | |
parent | 0fad6dd3c44a8d9352a3e73dbac5fd285ceafbdf (diff) | |
download | bcm5719-llvm-7cb25a888ce53c288de9369c5b98082b4ea5ec26.tar.gz bcm5719-llvm-7cb25a888ce53c288de9369c5b98082b4ea5ec26.zip |
[CodeGen] map sqrt libcalls to llvm.sqrt when errno is not set
The LLVM sqrt intrinsic definition changed with:
D28797
...so we don't have to use any relaxed FP settings other than errno handling.
This patch sidesteps a question raised in PR27435:
https://bugs.llvm.org/show_bug.cgi?id=27435
Is a programmer using __builtin_sqrt() invoking the compiler's intrinsic definition of sqrt or the mathlib definition of sqrt?
But we have an answer now: the builtin should match the behavior of the libm function including errno handling.
Differential Revision: https://reviews.llvm.org/D39204
llvm-svn: 317031
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 1de7c6e17d1..bc37afa2848 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2072,24 +2072,21 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, return RValue::get(nullptr); } - // Library functions with special handling. case Builtin::BIsqrt: case Builtin::BIsqrtf: - case Builtin::BIsqrtl: { - // Transform a call to sqrt* into a @llvm.sqrt.* intrinsic call, but only - // in finite- or unsafe-math mode (the intrinsic has different semantics - // for handling negative numbers compared to the library function, so - // -fmath-errno=0 is not enough). - if (!FD->hasAttr<ConstAttr>()) - break; - if (!(CGM.getCodeGenOpts().UnsafeFPMath || - CGM.getCodeGenOpts().NoNaNsFPMath)) - break; - Value *Arg0 = EmitScalarExpr(E->getArg(0)); - llvm::Type *ArgType = Arg0->getType(); - Value *F = CGM.getIntrinsic(Intrinsic::sqrt, ArgType); - return RValue::get(Builder.CreateCall(F, Arg0)); - } + case Builtin::BIsqrtl: + // Builtins have the same semantics as library functions. The LLVM intrinsic + // has the same semantics as the library function except it does not set + // errno. Thus, we can transform either sqrt or __builtin_sqrt to @llvm.sqrt + // if the call is 'const' (the call must not set errno). + // + // FIXME: The builtin cases are not here because they are marked 'const' in + // Builtins.def. So that means they are wrongly defined to have different + // semantics than the library functions. If we included them here, we would + // turn them into LLVM intrinsics regardless of whether -fmath-errno was on. + if (FD->hasAttr<ConstAttr>()) + return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::sqrt)); + break; case Builtin::BI__builtin_pow: case Builtin::BI__builtin_powf: |