diff options
| author | Chris Lattner <sabre@nondot.org> | 2010-05-06 05:35:16 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2010-05-06 05:35:16 +0000 | 
| commit | 43660c5bc00e052d92c065645393d00b9ff3463d (patch) | |
| tree | 8cc19c7d56599dc0ebe0308df6086af921ebb4ad /clang/lib/CodeGen/CGBuiltin.cpp | |
| parent | 2998b5458dda550ca77ccbc9c0969f81ba715e32 (diff) | |
| download | bcm5719-llvm-43660c5bc00e052d92c065645393d00b9ff3463d.tar.gz bcm5719-llvm-43660c5bc00e052d92c065645393d00b9ff3463d.zip | |
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
Diffstat (limited to 'clang/lib/CodeGen/CGBuiltin.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 36 | 
1 files changed, 35 insertions, 1 deletions
| diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 95c41db86e0..651539f0196 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -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! | 

