summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGBuiltin.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2016-04-07 14:29:05 +0000
committerSanjay Patel <spatel@rotateright.com>2016-04-07 14:29:05 +0000
commitae7a9df7bff5b548d8c16366ce17ac8a54db6fa6 (patch)
treeb7808aa35c28869ca9a4965936a0f63032c55ba5 /clang/lib/CodeGen/CGBuiltin.cpp
parentf90ec0e82e098d0a64070f4f16c6388821132430 (diff)
downloadbcm5719-llvm-ae7a9df7bff5b548d8c16366ce17ac8a54db6fa6.tar.gz
bcm5719-llvm-ae7a9df7bff5b548d8c16366ce17ac8a54db6fa6.zip
make __builtin_isfinite more efficient (PR27145)
isinf (is infinite) and isfinite should be implemented with the same function except we change the comparison operator. See PR27145 for more details: https://llvm.org/bugs/show_bug.cgi?id=27145 Ref: forked off of the discussion in D18513. Differential Revision: http://reviews.llvm.org/D18648 llvm-svn: 265675
Diffstat (limited to 'clang/lib/CodeGen/CGBuiltin.cpp')
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp31
1 files changed, 12 insertions, 19 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 878856f47ff..2397356d1fb 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -786,13 +786,19 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
}
- case Builtin::BI__builtin_isinf: {
- // isinf(x) --> fabs(x) == infinity
+ case Builtin::BI__builtin_isinf:
+ case Builtin::BI__builtin_isfinite: {
+ // isinf(x) --> fabs(x) == infinity
+ // isfinite(x) --> fabs(x) != infinity
+ // x != NaN via the ordered compare in either case.
Value *V = EmitScalarExpr(E->getArg(0));
- V = EmitFAbs(*this, V);
-
- V = Builder.CreateFCmpOEQ(V, ConstantFP::getInfinity(V->getType()),"isinf");
- return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
+ Value *Fabs = EmitFAbs(*this, V);
+ Constant *Infinity = ConstantFP::getInfinity(V->getType());
+ CmpInst::Predicate Pred = (BuiltinID == Builtin::BI__builtin_isinf)
+ ? CmpInst::FCMP_OEQ
+ : CmpInst::FCMP_ONE;
+ Value *FCmp = Builder.CreateFCmp(Pred, Fabs, Infinity, "cmpinf");
+ return RValue::get(Builder.CreateZExt(FCmp, ConvertType(E->getType())));
}
case Builtin::BI__builtin_isinf_sign: {
@@ -830,19 +836,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
}
- case Builtin::BI__builtin_isfinite: {
- // isfinite(x) --> x == x && fabs(x) != infinity;
- Value *V = EmitScalarExpr(E->getArg(0));
- Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq");
-
- Value *Abs = EmitFAbs(*this, V);
- Value *IsNotInf =
- Builder.CreateFCmpUNE(Abs, ConstantFP::getInfinity(V->getType()),"isinf");
-
- V = Builder.CreateAnd(Eq, IsNotInf, "and");
- return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
- }
-
case Builtin::BI__builtin_fpclassify: {
Value *V = EmitScalarExpr(E->getArg(5));
llvm::Type *Ty = ConvertType(E->getArg(5)->getType());
OpenPOWER on IntegriCloud