optimize builtin_isnan/isinf to not do an extraneous extension from

float -> double (which happens because they are modelled as int(...)
functions), and add a testcase for isinf.

llvm-svn: 103167
This commit is contained in:
Chris Lattner 2010-05-06 05:50:07 +00:00
parent 43660c5bc0
commit 68784efaf6
2 changed files with 32 additions and 1 deletions

View File

@ -607,12 +607,25 @@ bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {
if (OrigArg->isTypeDependent())
return false;
// This operation requires a floating-point number
// This operation requires a non-_Complex floating-point number.
if (!OrigArg->getType()->isRealFloatingType())
return Diag(OrigArg->getLocStart(),
diag::err_typecheck_call_invalid_unary_fp)
<< OrigArg->getType() << OrigArg->getSourceRange();
// If this is an implicit conversion from float -> double, remove it.
if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(OrigArg)) {
Expr *CastArg = Cast->getSubExpr();
if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) {
assert(Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) &&
"promotion from float to double is the only expected cast here");
Cast->setSubExpr(0);
Cast->Destroy(Context);
TheCall->setArg(NumArgs-1, CastArg);
OrigArg = CastArg;
}
}
return false;
}

View File

@ -163,3 +163,21 @@ void bar() {
}
// CHECK: }
// CHECK: define void @test_inff
void test_inff(float F, double D, long double LD) {
volatile int res;
res = __builtin_isinf(F);
// CHECK: call float @fabsf(float
// CHECK: fcmp oeq float {{.*}}, 0x7FF0000000000000
res = __builtin_isinf(D);
// CHECK: call double @fabs(double
// CHECK: fcmp oeq double {{.*}}, 0x7FF0000000000000
res = __builtin_isinf(LD);
// CHECK: call x86_fp80 @fabsl(x86_fp80
// CHECK: fcmp oeq x86_fp80 {{.*}}, 0xK7FFF8000000000000000
}