forked from OSchip/llvm-project
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
This commit is contained in:
parent
f90ec0e82e
commit
ae7a9df7bf
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue