[cfe-commits] r52914 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/Builtins.def include/clang/Basic/TargetInfo.h lib/AST/ASTContext.cpp lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CGExprScalar.cpp lib/CodeGen/CodeGenTypes.cpp lib/CodeGen/CodeGenTypes.h lib/Sema/SemaChecking.cpp lib/Sema/SemaExpr.cpp

Chris Lattner sabre at nondot.org
Mon Jun 30 11:32:55 PDT 2008


Author: lattner
Date: Mon Jun 30 13:32:54 2008
New Revision: 52914

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



Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Builtins.def
    cfe/trunk/include/clang/Basic/TargetInfo.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
    cfe/trunk/lib/CodeGen/CodeGenTypes.h
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=52914&r1=52913&r2=52914&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Jun 30 13:32:54 2008
@@ -26,6 +26,10 @@
 #include "llvm/Support/Allocator.h"
 #include <vector>
 
+namespace llvm {
+  struct fltSemantics;
+}
+
 namespace clang {
   class TargetInfo;
   class IdentifierTable;
@@ -285,6 +289,10 @@
   //                         Type Sizing and Analysis
   //===--------------------------------------------------------------------===//
   
+  /// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified
+  /// scalar floating point type.
+  const llvm::fltSemantics &getFloatTypeSemantics(QualType T) const;
+  
   /// getTypeInfo - Get the size and alignment of the specified complete type in
   /// bits.
   std::pair<uint64_t, unsigned> getTypeInfo(QualType T);

Modified: cfe/trunk/include/clang/AST/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Builtins.def?rev=52914&r1=52913&r2=52914&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Builtins.def (original)
+++ cfe/trunk/include/clang/AST/Builtins.def Mon Jun 30 13:32:54 2008
@@ -54,14 +54,17 @@
 //  F -> this is a libc/libm function with a '__builtin_' prefix added.
 
 // Standard libc/libm functions:
+BUILTIN(__builtin_huge_val, "d", "nc")
 BUILTIN(__builtin_inf  , "d"   , "nc")
 BUILTIN(__builtin_inff , "f"   , "nc")
 BUILTIN(__builtin_infl , "Ld"  , "nc")
+BUILTIN(__builtin_nan,  "dcC*" , "ncF")
+BUILTIN(__builtin_nanf, "fcC*" , "ncF")
+BUILTIN(__builtin_nanl, "LdcC*", "ncF")
 BUILTIN(__builtin_abs  , "ii"  , "ncF")
 BUILTIN(__builtin_fabs , "dd"  , "ncF")
 BUILTIN(__builtin_fabsf, "ff"  , "ncF")
 BUILTIN(__builtin_fabsl, "LdLd", "ncF")
-BUILTIN(__builtin_huge_val, "d", "nc")
 BUILTIN(__builtin_copysign, "ddd", "ncF")
 BUILTIN(__builtin_copysignf, "fff", "ncF")
 BUILTIN(__builtin_copysignl, "LdLdLd", "ncF")

Modified: cfe/trunk/include/clang/Basic/TargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TargetInfo.h?rev=52914&r1=52913&r2=52914&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/TargetInfo.h (original)
+++ cfe/trunk/include/clang/Basic/TargetInfo.h Mon Jun 30 13:32:54 2008
@@ -118,19 +118,19 @@
   /// getFloatWidth/Align/Format - Return the size/align/format of 'float'.
   unsigned getFloatWidth() const { return FloatWidth; }
   unsigned getFloatAlign() const { return FloatAlign; }
-  const llvm::fltSemantics *getFloatFormat() const { return FloatFormat; }
+  const llvm::fltSemantics &getFloatFormat() const { return *FloatFormat; }
 
   /// getDoubleWidth/Align/Format - Return the size/align/format of 'double'.
   unsigned getDoubleWidth() const { return DoubleWidth; }
   unsigned getDoubleAlign() const { return DoubleAlign; }
-  const llvm::fltSemantics *getDoubleFormat() const { return DoubleFormat; }
+  const llvm::fltSemantics &getDoubleFormat() const { return *DoubleFormat; }
 
   /// getLongDoubleWidth/Align/Format - Return the size/align/format of 'long
   /// double'.
   unsigned getLongDoubleWidth() const { return LongDoubleWidth; }
   unsigned getLongDoubleAlign() const { return LongDoubleAlign; }
-  const llvm::fltSemantics *getLongDoubleFormat() const {
-    return LongDoubleFormat;
+  const llvm::fltSemantics &getLongDoubleFormat() const {
+    return *LongDoubleFormat;
   }
   
   /// getIntMaxTWidth - Return the size of intmax_t and uintmax_t for this

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=52914&r1=52913&r2=52914&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Jun 30 13:32:54 2008
@@ -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>

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=52914&r1=52913&r2=52914&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Mon Jun 30 13:32:54 2008
@@ -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;
-      
-      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);
-      }
+  default: break;  // Handle intrinsics and libm functions below.
       
-      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) {

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=52914&r1=52913&r2=52914&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Mon Jun 30 13:32:54 2008
@@ -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");

Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=52914&r1=52913&r2=52914&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Mon Jun 30 13:32:54 2008
@@ -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;
   }

Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.h?rev=52914&r1=52913&r2=52914&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.h Mon Jun 30 13:32:54 2008
@@ -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

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=52914&r1=52913&r2=52914&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Jun 30 13:32:54 2008
@@ -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:

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=52914&r1=52913&r2=52914&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jun 30 13:32:54 2008
@@ -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()) {





More information about the cfe-commits mailing list