Skip to content

Commit

Permalink
make __builtin_isfinite more efficient (PR27145)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rotateright committed Apr 7, 2016
1 parent f90ec0e commit ae7a9df
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 22 deletions.
31 changes: 12 additions & 19 deletions clang/lib/CodeGen/CGBuiltin.cpp
Expand Up @@ -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: {
Expand Down Expand Up @@ -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());
Expand Down
4 changes: 1 addition & 3 deletions clang/test/CodeGen/builtins.c
Expand Up @@ -217,10 +217,8 @@ void test_float_builtins(float F, double D, long double LD) {
// CHECK: select i1 %[[ISINF]], i32 %[[SIGN]], i32 0

res = __builtin_isfinite(F);
// CHECK: fcmp oeq float
// CHECK: call float @llvm.fabs.f32(float
// CHECK: fcmp une float {{.*}}, 0x7FF0000000000000
// CHECK: and i1
// CHECK: fcmp one float {{.*}}, 0x7FF0000000000000

res = __builtin_isnormal(F);
// CHECK: fcmp oeq float
Expand Down

0 comments on commit ae7a9df

Please sign in to comment.