diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGBuiltin.cpp | 167 | ||||
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.cpp | 18 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.h | 2 |
4 files changed, 101 insertions, 88 deletions
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 1113e2f422..a6a479a87d 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -38,74 +38,8 @@ static RValue EmitBinaryAtomic(CodeGenFunction& CFG, 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(); + default: break; // Handle intrinsics and libm functions below. - 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 @@ RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { 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 @@ RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { 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 ce49cb20d3..5a4236a42c 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -613,7 +613,7 @@ Value *ScalarExprEmitter::VisitPrePostIncDec(const UnaryOperator *E, 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 9074e8179c..41ec2dd0f7 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -168,18 +168,18 @@ const llvm::Type *CodeGenTypes::ConvertReturnType(QualType T) { 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 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { 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 6c958e65e8..536e881f8d 100644 --- a/lib/CodeGen/CodeGenTypes.h +++ b/lib/CodeGen/CodeGenTypes.h @@ -143,7 +143,7 @@ public: 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 |