diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-02-16 22:43:43 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-02-16 22:43:43 +0000 |
commit | ef2abfee3ea16ec74942dc09e9e425f46aeb2582 (patch) | |
tree | a1fd544522e1d5e2708b9b2a6df1704a0734d0bd /lib/CodeGen | |
parent | f592c929bd1f083abcc8199b24bb825fdd28df1c (diff) |
Support IRgen of sqrt -> llvm.sqrt, pow -> llvm.pow.
- Define pow[lf]?, sqrt[lf]? as builtins.
- Add -fmath-errno option which binds to LangOptions.MathErrno
- Add new builtin flag Builtin::Context::isConstWithoutErrno for
functions which can be marked as const if errno isn't respected for
math functions. Sema automatically marks these functions as const
when they are defined, if MathErrno=0.
- IRgen uses const attribute on sqrt and pow library functions to
decide if it can use the llvm intrinsic.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64689 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGBuiltin.cpp | 31 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 3 |
3 files changed, 33 insertions, 3 deletions
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index b990c19995..6e59226a6e 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -36,7 +36,8 @@ static RValue EmitBinaryAtomic(CodeGenFunction& CFG, CFG.EmitScalarExpr(E->getArg(1)))); } -RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { +RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, + unsigned BuiltinID, const CallExpr *E) { // See if we can constant fold this builtin. If so, don't emit it at all. Expr::EvalResult Result; if (E->Evaluate(Result, CGM.getContext())) { @@ -324,6 +325,34 @@ RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { } case Builtin::BI__sync_lock_test_and_set: return EmitBinaryAtomic(*this, Intrinsic::atomic_swap, E); + + + // Library functions with special handling. + + case Builtin::BIsqrt: + case Builtin::BIsqrtf: + case Builtin::BIsqrtl: { + // Rewrite sqrt to intrinsic if allowed. + if (!FD->getAttr<ConstAttr>()) + break; + Value *Arg0 = EmitScalarExpr(E->getArg(0)); + const llvm::Type *ArgType = Arg0->getType(); + Value *F = CGM.getIntrinsic(Intrinsic::sqrt, &ArgType, 1); + return RValue::get(Builder.CreateCall(F, Arg0, "tmp")); + } + + case Builtin::BIpow: + case Builtin::BIpowf: + case Builtin::BIpowl: { + // Rewrite sqrt to intrinsic if allowed. + if (!FD->getAttr<ConstAttr>()) + break; + Value *Base = EmitScalarExpr(E->getArg(0)); + Value *Exponent = EmitScalarExpr(E->getArg(1)); + const llvm::Type *ArgType = Base->getType(); + Value *F = CGM.getIntrinsic(Intrinsic::pow, &ArgType, 1); + return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp")); + } } // If this is an alias for a libm function (e.g. __builtin_sin) turn it into diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 4dc8a9e1d4..b151dd2102 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -969,7 +969,7 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) { if (const FunctionDecl *FDecl = dyn_cast<const FunctionDecl>(DRExpr->getDecl())) if (unsigned builtinID = FDecl->getBuiltinID(getContext())) - return EmitBuiltinExpr(builtinID, E); + return EmitBuiltinExpr(FDecl, builtinID, E); if (E->getCallee()->getType()->isBlockPointerType()) return EmitBlockCallExpr(E); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 5f42a429e0..7f36c71ab6 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -631,7 +631,8 @@ public: CallExpr::const_arg_iterator ArgBeg, CallExpr::const_arg_iterator ArgEnd); - RValue EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E); + RValue EmitBuiltinExpr(const FunctionDecl *FD, + unsigned BuiltinID, const CallExpr *E); RValue EmitBlockCallExpr(const CallExpr *E); |