Make a few related changes:

1) add a new ASTContext::getFloatTypeSemantics method.
2) Use it from SemaExpr.cpp, CodeGenTypes.cpp and other places.
3) Change the TargetInfo.h get*Format methods to return their 
   fltSemantics byref instead of by pointer.
4) Change CodeGenFunction::EmitBuiltinExpr to allow builtins which
   sometimes expand specially and othertimes fall back to libm.
5) Add support for __builtin_nan("") to codegen, cases that don't pass
   in an empty string are currently lowered to libm calls.
6) Fix codegen of __builtin_infl.




git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52914 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 08a2bb1..fa12364 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -182,6 +182,20 @@
 //                         Type Sizing and Analysis
 //===----------------------------------------------------------------------===//
 
+/// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified
+/// scalar floating point type.
+const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
+  const BuiltinType *BT = T->getAsBuiltinType();
+  assert(BT && "Not a floating point type!");
+  switch (BT->getKind()) {
+  default: assert(0 && "Not a floating point type!");
+  case BuiltinType::Float:      return Target.getFloatFormat();
+  case BuiltinType::Double:     return Target.getDoubleFormat();
+  case BuiltinType::LongDouble: return Target.getLongDoubleFormat();
+  }
+}
+
+
 /// getTypeSize - Return the size of the specified type, in bits.  This method
 /// does not work on incomplete types.
 std::pair<uint64_t, unsigned>
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 1113e2f..a6a479a 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -38,74 +38,8 @@
 
 RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
   switch (BuiltinID) {
-  default: {
-    if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
-      return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID), 
-                          E->getCallee()->getType(), E->arg_begin(),
-                          E->arg_end());
-  
-    // See if we have a target specific intrinsic.
-    Intrinsic::ID IntrinsicID;
-    const char *TargetPrefix = Target.getTargetPrefix();
-    const char *BuiltinName = getContext().BuiltinInfo.GetName(BuiltinID);
-#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
-#include "llvm/Intrinsics.gen"
-#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
-    
-    if (IntrinsicID != Intrinsic::not_intrinsic) {
-      SmallVector<Value*, 16> Args;
+  default: break;  // Handle intrinsics and libm functions below.
       
-      Function *F = CGM.getIntrinsic(IntrinsicID);
-      const llvm::FunctionType *FTy = F->getFunctionType();
-      
-      for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
-        Value *ArgValue = EmitScalarExpr(E->getArg(i));
-  
-        // If the intrinsic arg type is different from the builtin arg type
-        // we need to do a bit cast.
-        const llvm::Type *PTy = FTy->getParamType(i);
-        if (PTy != ArgValue->getType()) {
-          assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) &&
-                 "Must be able to losslessly bit cast to param");
-          ArgValue = Builder.CreateBitCast(ArgValue, PTy);
-        }
-
-        Args.push_back(ArgValue);
-      }
-            
-      Value *V = Builder.CreateCall(F, &Args[0], &Args[0] + Args.size());
-      QualType BuiltinRetType = E->getType();
-      
-      const llvm::Type *RetTy = llvm::Type::VoidTy;
-      if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType);
-
-      if (RetTy != V->getType()) {
-        assert(V->getType()->canLosslesslyBitCastTo(RetTy) &&
-               "Must be able to losslessly bit cast result type");
-        V = Builder.CreateBitCast(V, RetTy);
-      }
-      
-      return RValue::get(V);
-    }
-
-    // See if we have a target specific builtin that needs to be lowered.
-    Value *V = 0;
-    
-    if (strcmp(TargetPrefix, "x86") == 0)
-      V = EmitX86BuiltinExpr(BuiltinID, E);
-    else if (strcmp(TargetPrefix, "ppc") == 0)
-      V = EmitPPCBuiltinExpr(BuiltinID, E);
-
-    if (V)
-      return RValue::get(V);
-    
-    WarnUnsupported(E, "builtin function");
-
-    // Unknown builtin, for now just dump it out and return undef.
-    if (hasAggregateLLVMType(E->getType()))
-      return RValue::getAggregate(CreateTempAlloca(ConvertType(E->getType())));
-    return RValue::get(UndefValue::get(ConvertType(E->getType())));
-  }    
   case Builtin::BI__builtin___CFStringMakeConstantString: {
     const Expr *Arg = E->getArg(0);
     
@@ -214,16 +148,29 @@
     Value *F = CGM.getIntrinsic(Intrinsic::bswap, &ArgType, 1);
     return RValue::get(Builder.CreateCall(F, ArgValue, "tmp"));
   }
-  case Builtin::BI__builtin_inff: {
-    APFloat f(APFloat::IEEEsingle, APFloat::fcInfinity, false);
-    return RValue::get(ConstantFP::get(f));
-  }
+  case Builtin::BI__builtin_inff:
   case Builtin::BI__builtin_huge_val:
   case Builtin::BI__builtin_inf:
-  // FIXME: mapping long double onto double.      
   case Builtin::BI__builtin_infl: {
-    APFloat f(APFloat::IEEEdouble, APFloat::fcInfinity, false);
-    return RValue::get(ConstantFP::get(f));
+    const llvm::fltSemantics &Sem =
+      CGM.getContext().getFloatTypeSemantics(E->getType());
+    return RValue::get(ConstantFP::get(APFloat::getInf(Sem)));
+  }
+  case Builtin::BI__builtin_nanf:
+  case Builtin::BI__builtin_nan:
+  case Builtin::BI__builtin_nanl: {
+    // If this is __builtin_nan("") turn this into a simple nan, otherwise just
+    // call libm nan.
+    if (const StringLiteral *S = 
+          dyn_cast<StringLiteral>(E->getArg(0)->IgnoreParenCasts())) {
+      if (!S->isWide() && S->getByteLength() == 0) { // empty string.
+        const llvm::fltSemantics &Sem = 
+          CGM.getContext().getFloatTypeSemantics(E->getType());
+        return RValue::get(ConstantFP::get(APFloat::getNaN(Sem)));
+      }
+    }
+    // Otherwise, call libm 'nan'.
+    break;
   }
   case Builtin::BI__builtin_isgreater:
   case Builtin::BI__builtin_isgreaterequal:
@@ -316,8 +263,76 @@
   case Builtin::BI__sync_lock_test_and_set:
     return EmitBinaryAtomic(*this, Intrinsic::atomic_swap, E);
   }
-  return RValue::get(0);
-}
+  
+  // If this is an alias for a libm function (e.g. __builtin_sin) turn it into
+  // that function.
+  if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
+    return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID), 
+                        E->getCallee()->getType(), E->arg_begin(),
+                        E->arg_end());
+  
+  // See if we have a target specific intrinsic.
+  Intrinsic::ID IntrinsicID;
+  const char *TargetPrefix = Target.getTargetPrefix();
+  const char *BuiltinName = getContext().BuiltinInfo.GetName(BuiltinID);
+#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
+#include "llvm/Intrinsics.gen"
+#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
+  
+  if (IntrinsicID != Intrinsic::not_intrinsic) {
+    SmallVector<Value*, 16> Args;
+    
+    Function *F = CGM.getIntrinsic(IntrinsicID);
+    const llvm::FunctionType *FTy = F->getFunctionType();
+    
+    for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
+      Value *ArgValue = EmitScalarExpr(E->getArg(i));
+      
+      // If the intrinsic arg type is different from the builtin arg type
+      // we need to do a bit cast.
+      const llvm::Type *PTy = FTy->getParamType(i);
+      if (PTy != ArgValue->getType()) {
+        assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) &&
+               "Must be able to losslessly bit cast to param");
+        ArgValue = Builder.CreateBitCast(ArgValue, PTy);
+      }
+      
+      Args.push_back(ArgValue);
+    }
+    
+    Value *V = Builder.CreateCall(F, &Args[0], &Args[0] + Args.size());
+    QualType BuiltinRetType = E->getType();
+    
+    const llvm::Type *RetTy = llvm::Type::VoidTy;
+    if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType);
+    
+    if (RetTy != V->getType()) {
+      assert(V->getType()->canLosslesslyBitCastTo(RetTy) &&
+             "Must be able to losslessly bit cast result type");
+      V = Builder.CreateBitCast(V, RetTy);
+    }
+    
+    return RValue::get(V);
+  }
+  
+  // See if we have a target specific builtin that needs to be lowered.
+  Value *V = 0;
+  
+  if (strcmp(TargetPrefix, "x86") == 0)
+    V = EmitX86BuiltinExpr(BuiltinID, E);
+  else if (strcmp(TargetPrefix, "ppc") == 0)
+    V = EmitPPCBuiltinExpr(BuiltinID, E);
+  
+  if (V)
+    return RValue::get(V);
+  
+  WarnUnsupported(E, "builtin function");
+  
+  // Unknown builtin, for now just dump it out and return undef.
+  if (hasAggregateLLVMType(E->getType()))
+    return RValue::getAggregate(CreateTempAlloca(ConvertType(E->getType())));
+  return RValue::get(UndefValue::get(ConvertType(E->getType())));
+}    
 
 Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 
                                            const CallExpr *E) {
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index ce49cb2..5a4236a 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -613,7 +613,7 @@
         llvm::ConstantFP::get(llvm::APFloat(static_cast<double>(AmountVal)));
     else {
       llvm::APFloat F(static_cast<float>(AmountVal));
-      F.convert(*CGF.Target.getLongDoubleFormat(), llvm::APFloat::rmTowardZero);
+      F.convert(CGF.Target.getLongDoubleFormat(), llvm::APFloat::rmTowardZero);
       NextVal = llvm::ConstantFP::get(F);
     }
     NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 9074e81..41ec2dd 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -168,18 +168,18 @@
     return ConvertType(T);
 }
 
-static const llvm::Type* getTypeForFormat(const llvm::fltSemantics * format) {
-  if (format == &llvm::APFloat::IEEEsingle)
+static const llvm::Type* getTypeForFormat(const llvm::fltSemantics &format) {
+  if (&format == &llvm::APFloat::IEEEsingle)
     return llvm::Type::FloatTy;
-  if (format == &llvm::APFloat::IEEEdouble)
+  if (&format == &llvm::APFloat::IEEEdouble)
     return llvm::Type::DoubleTy;
-  if (format == &llvm::APFloat::IEEEquad)
+  if (&format == &llvm::APFloat::IEEEquad)
     return llvm::Type::FP128Ty;
-  if (format == &llvm::APFloat::PPCDoubleDouble)
+  if (&format == &llvm::APFloat::PPCDoubleDouble)
     return llvm::Type::PPC_FP128Ty;
-  if (format == &llvm::APFloat::x87DoubleExtended)
+  if (&format == &llvm::APFloat::x87DoubleExtended)
     return llvm::Type::X86_FP80Ty;
-  assert(9 && "Unknown float format!");
+  assert(0 && "Unknown float format!");
   return 0;
 }
 
@@ -218,11 +218,9 @@
         static_cast<unsigned>(Context.getTypeSize(T)));
       
     case BuiltinType::Float:
-      return getTypeForFormat(Context.Target.getFloatFormat());
     case BuiltinType::Double:
-      return getTypeForFormat(Context.Target.getDoubleFormat());
     case BuiltinType::LongDouble:
-      return getTypeForFormat(Context.Target.getLongDoubleFormat());
+      return getTypeForFormat(Context.getFloatTypeSemantics(T));
     }
     break;
   }
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index 6c958e6..536e881 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -143,7 +143,7 @@
   const llvm::Type *ConvertTypeForMem(QualType T);
   
   void CollectObjCIvarTypes(ObjCInterfaceDecl *ObjCClass,
-      std::vector<const llvm::Type*> &IvarTypes);
+                            std::vector<const llvm::Type*> &IvarTypes);
   
   const CGRecordLayout *getCGRecordLayout(const TagDecl*) const;
   /// Returns a StructType representing an Objective-C object
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 9008884..b328b2f 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -46,9 +46,8 @@
       return true;
     return TheCall.take();
   case Builtin::BI__builtin_va_start:
-    if (SemaBuiltinVAStart(TheCall.get())) {
+    if (SemaBuiltinVAStart(TheCall.get()))
       return true;
-    }
     return TheCall.take();
   case Builtin::BI__builtin_isgreater:
   case Builtin::BI__builtin_isgreaterequal:
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 8ef9486..32d7a60 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -214,23 +214,18 @@
   
   if (Literal.isFloatingLiteral()) {
     QualType Ty;
-    const llvm::fltSemantics *Format;
-
-    if (Literal.isFloat) {
+    if (Literal.isFloat)
       Ty = Context.FloatTy;
-      Format = Context.Target.getFloatFormat();
-    } else if (!Literal.isLong) {
+    else if (!Literal.isLong)
       Ty = Context.DoubleTy;
-      Format = Context.Target.getDoubleFormat();
-    } else {
+    else
       Ty = Context.LongDoubleTy;
-      Format = Context.Target.getLongDoubleFormat();
-    }
-    
+
+    const llvm::fltSemantics &Format = Context.getFloatTypeSemantics(Ty);
+
     // isExact will be set by GetFloatValue().
     bool isExact = false;
-    
-    Res = new FloatingLiteral(Literal.GetFloatValue(*Format,&isExact), &isExact, 
+    Res = new FloatingLiteral(Literal.GetFloatValue(Format, &isExact), &isExact,
                               Ty, Tok.getLocation());
     
   } else if (!Literal.isIntegerLiteral()) {