forked from OSchip/llvm-project
implement part of PR6083: codegen support for isinf. Like isnan,
this is generating correct but suboptimal (extra extend to double) code for the float case. Will investigate next. llvm-svn: 103166
This commit is contained in:
parent
2998b5458d
commit
43660c5bc0
|
@ -71,7 +71,7 @@ static RValue EmitBinaryAtomic(CodeGenFunction &CGF,
|
|||
/// Utility to insert an atomic instruction based Instrinsic::ID and
|
||||
// the expression node, where the return value is the result of the
|
||||
// operation.
|
||||
static RValue EmitBinaryAtomicPost(CodeGenFunction& CGF,
|
||||
static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF,
|
||||
Intrinsic::ID Id, const CallExpr *E,
|
||||
Instruction::BinaryOps Op) {
|
||||
const llvm::Type *ResType[2];
|
||||
|
@ -88,6 +88,30 @@ static llvm::ConstantInt *getInt32(llvm::LLVMContext &Context, int32_t Value) {
|
|||
return llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), Value);
|
||||
}
|
||||
|
||||
|
||||
/// EmitFAbs - Emit a call to fabs/fabsf/fabsl, depending on the type of ValTy,
|
||||
/// which must be a scalar floating point type.
|
||||
static Value *EmitFAbs(CodeGenFunction &CGF, Value *V, QualType ValTy) {
|
||||
const BuiltinType *ValTyP = ValTy->getAs<BuiltinType>();
|
||||
assert(ValTyP && "isn't scalar fp type!");
|
||||
|
||||
StringRef FnName;
|
||||
switch (ValTyP->getKind()) {
|
||||
default: assert(0 && "Isn't a scalar fp type!");
|
||||
case BuiltinType::Float: FnName = "fabsf"; break;
|
||||
case BuiltinType::Double: FnName = "fabs"; break;
|
||||
case BuiltinType::LongDouble: FnName = "fabsl"; break;
|
||||
}
|
||||
|
||||
// The prototype is something that takes and returns whatever V's type is.
|
||||
std::vector<const llvm::Type*> Args;
|
||||
Args.push_back(V->getType());
|
||||
llvm::FunctionType *FT = llvm::FunctionType::get(V->getType(), Args, false);
|
||||
llvm::Value *Fn = CGF.CGM.CreateRuntimeFunction(FT, FnName);
|
||||
|
||||
return CGF.Builder.CreateCall(Fn, V, "abs");
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -328,6 +352,16 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
|||
V = Builder.CreateFCmpUNO(V, V, "cmp");
|
||||
return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()), "tmp"));
|
||||
}
|
||||
|
||||
case Builtin::BI__builtin_isinf: {
|
||||
// isinf(x) --> fabs(x) == infinity
|
||||
Value *V = EmitScalarExpr(E->getArg(0));
|
||||
V = EmitFAbs(*this, V, E->getArg(0)->getType());
|
||||
|
||||
V = Builder.CreateFCmpOEQ(V, ConstantFP::getInfinity(V->getType()),"isinf");
|
||||
return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()), "tmp"));
|
||||
}
|
||||
|
||||
case Builtin::BIalloca:
|
||||
case Builtin::BI__builtin_alloca: {
|
||||
// FIXME: LLVM IR Should allow alloca with an i64 size!
|
||||
|
|
Loading…
Reference in New Issue