[cfe-commits] r103166 - /cfe/trunk/lib/CodeGen/CGBuiltin.cpp

Chris Lattner sabre at nondot.org
Wed May 5 22:35:16 PDT 2010


Author: lattner
Date: Thu May  6 00:35:16 2010
New Revision: 103166

URL: http://llvm.org/viewvc/llvm-project?rev=103166&view=rev
Log:
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.

Modified:
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=103166&r1=103165&r2=103166&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Thu May  6 00:35:16 2010
@@ -71,7 +71,7 @@
 /// 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 @@
   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 @@
     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!





More information about the cfe-commits mailing list