summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2017-10-31 20:19:39 +0000
committerSanjay Patel <spatel@rotateright.com>2017-10-31 20:19:39 +0000
commit7cb25a888ce53c288de9369c5b98082b4ea5ec26 (patch)
tree298d75644c31f5c8a0594f00cb3936d876eb2413 /clang/lib
parent0fad6dd3c44a8d9352a3e73dbac5fd285ceafbdf (diff)
downloadbcm5719-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.cpp29
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:
OpenPOWER on IntegriCloud