diff options
author | Tanya Lattner <tonic@nondot.org> | 2008-10-22 05:05:36 +0000 |
---|---|---|
committer | Tanya Lattner <tonic@nondot.org> | 2008-10-22 05:05:36 +0000 |
commit | b9c01c2c6f1f1371440af1e5b0b01245ae060d0a (patch) | |
tree | 935b89b7ee832f6f160dc446d5d96a23d58d2a1b | |
parent | c6c313a84b6be689125c0af8cb06e4e69da739f0 (diff) |
Merge from mainline.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_24@57957 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/CBackend/CBackend.cpp | 125 | ||||
-rw-r--r-- | test/CodeGen/CBackend/2008-10-21-PPCLongDoubleConstant.ll | 29 |
2 files changed, 107 insertions, 47 deletions
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 1700c1eb42..0e01c3008c 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -88,12 +88,15 @@ namespace { std::map<const ConstantFP *, unsigned> FPConstantMap; std::set<Function*> intrinsicPrototypesAlreadyGenerated; std::set<const Argument*> ByValParams; + unsigned FPCounter; public: static char ID; explicit CWriter(raw_ostream &o) : FunctionPass(&ID), Out(o), IL(0), Mang(0), LI(0), - TheModule(0), TAsm(0), TD(0) {} + TheModule(0), TAsm(0), TD(0) { + FPCounter = 0; + } virtual const char *getPassName() const { return "C backend"; } @@ -181,6 +184,7 @@ namespace { void printModuleTypes(const TypeSymbolTable &ST); void printContainedStructs(const Type *Ty, std::set<const Type *> &); void printFloatingPointConstants(Function &F); + void printFloatingPointConstants(const Constant *C); void printFunctionSignature(const Function *F, bool Prototype); void printFunction(Function &); @@ -833,10 +837,10 @@ void CWriter::printConstantVector(ConstantVector *CP, bool Static) { // static bool isFPCSafeToPrint(const ConstantFP *CFP) { // Do long doubles in hex for now. - if (CFP->getType()!=Type::FloatTy && CFP->getType()!=Type::DoubleTy) + if (CFP->getType() != Type::FloatTy && CFP->getType() != Type::DoubleTy) return false; APFloat APF = APFloat(CFP->getValueAPF()); // copy - if (CFP->getType()==Type::FloatTy) + if (CFP->getType() == Type::FloatTy) APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven); #if HAVE_PRINTF_A && ENABLE_CBE_PRINTF_A char Buffer[100]; @@ -1128,11 +1132,21 @@ void CWriter::printConstant(Constant *CPV, bool Static) { "long double") << "*)&FPConstant" << I->second << ')'; } else { - assert(FPC->getType() == Type::FloatTy || - FPC->getType() == Type::DoubleTy); - double V = FPC->getType() == Type::FloatTy ? - FPC->getValueAPF().convertToFloat() : - FPC->getValueAPF().convertToDouble(); + double V; + if (FPC->getType() == Type::FloatTy) + V = FPC->getValueAPF().convertToFloat(); + else if (FPC->getType() == Type::DoubleTy) + V = FPC->getValueAPF().convertToDouble(); + else { + // Long double. Convert the number to double, discarding precision. + // This is not awesome, but it at least makes the CBE output somewhat + // useful. + APFloat Tmp = FPC->getValueAPF(); + bool LosesInfo; + Tmp.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &LosesInfo); + V = Tmp.convertToDouble(); + } + if (IsNAN(V)) { // The value is NaN @@ -2018,51 +2032,68 @@ void CWriter::printFloatingPointConstants(Function &F) { // the precision of the printed form, unless the printed form preserves // precision. // - static unsigned FPCounter = 0; for (constant_iterator I = constant_begin(&F), E = constant_end(&F); I != E; ++I) - if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I)) - if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe. - !FPConstantMap.count(FPC)) { - FPConstantMap[FPC] = FPCounter; // Number the FP constants - - if (FPC->getType() == Type::DoubleTy) { - double Val = FPC->getValueAPF().convertToDouble(); - uint64_t i = FPC->getValueAPF().convertToAPInt().getZExtValue(); - Out << "static const ConstantDoubleTy FPConstant" << FPCounter++ - << " = 0x" << utohexstr(i) - << "ULL; /* " << Val << " */\n"; - } else if (FPC->getType() == Type::FloatTy) { - float Val = FPC->getValueAPF().convertToFloat(); - uint32_t i = (uint32_t)FPC->getValueAPF().convertToAPInt(). - getZExtValue(); - Out << "static const ConstantFloatTy FPConstant" << FPCounter++ - << " = 0x" << utohexstr(i) - << "U; /* " << Val << " */\n"; - } else if (FPC->getType() == Type::X86_FP80Ty) { - // api needed to prevent premature destruction - APInt api = FPC->getValueAPF().convertToAPInt(); - const uint64_t *p = api.getRawData(); - Out << "static const ConstantFP80Ty FPConstant" << FPCounter++ - << " = { 0x" - << utohexstr((uint16_t)p[1] | (p[0] & 0xffffffffffffLL)<<16) - << "ULL, 0x" << utohexstr((uint16_t)(p[0] >> 48)) << ",{0,0,0}" - << "}; /* Long double constant */\n"; - } else if (FPC->getType() == Type::PPC_FP128Ty) { - APInt api = FPC->getValueAPF().convertToAPInt(); - const uint64_t *p = api.getRawData(); - Out << "static const ConstantFP128Ty FPConstant" << FPCounter++ - << " = { 0x" - << utohexstr(p[0]) << ", 0x" << utohexstr(p[1]) - << "}; /* Long double constant */\n"; - - } else - assert(0 && "Unknown float type!"); - } + printFloatingPointConstants(*I); Out << '\n'; } +void CWriter::printFloatingPointConstants(const Constant *C) { + // If this is a constant expression, recursively check for constant fp values. + if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) { + for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) + printFloatingPointConstants(CE->getOperand(i)); + return; + } + + // Otherwise, check for a FP constant that we need to print. + const ConstantFP *FPC = dyn_cast<ConstantFP>(C); + if (FPC == 0 || + // Do not put in FPConstantMap if safe. + isFPCSafeToPrint(FPC) || + // Already printed this constant? + FPConstantMap.count(FPC)) + return; + + FPConstantMap[FPC] = FPCounter; // Number the FP constants + + if (FPC->getType() == Type::DoubleTy) { + double Val = FPC->getValueAPF().convertToDouble(); + uint64_t i = FPC->getValueAPF().bitcastToAPInt().getZExtValue(); + Out << "static const ConstantDoubleTy FPConstant" << FPCounter++ + << " = 0x" << utohexstr(i) + << "ULL; /* " << Val << " */\n"; + } else if (FPC->getType() == Type::FloatTy) { + float Val = FPC->getValueAPF().convertToFloat(); + uint32_t i = (uint32_t)FPC->getValueAPF().bitcastToAPInt(). + getZExtValue(); + Out << "static const ConstantFloatTy FPConstant" << FPCounter++ + << " = 0x" << utohexstr(i) + << "U; /* " << Val << " */\n"; + } else if (FPC->getType() == Type::X86_FP80Ty) { + // api needed to prevent premature destruction + APInt api = FPC->getValueAPF().bitcastToAPInt(); + const uint64_t *p = api.getRawData(); + Out << "static const ConstantFP80Ty FPConstant" << FPCounter++ + << " = { 0x" + << utohexstr((uint16_t)p[1] | (p[0] & 0xffffffffffffLL)<<16) + << "ULL, 0x" << utohexstr((uint16_t)(p[0] >> 48)) << ",{0,0,0}" + << "}; /* Long double constant */\n"; + } else if (FPC->getType() == Type::PPC_FP128Ty) { + APInt api = FPC->getValueAPF().bitcastToAPInt(); + const uint64_t *p = api.getRawData(); + Out << "static const ConstantFP128Ty FPConstant" << FPCounter++ + << " = { 0x" + << utohexstr(p[0]) << ", 0x" << utohexstr(p[1]) + << "}; /* Long double constant */\n"; + + } else { + assert(0 && "Unknown float type!"); + } +} + + /// printSymbolTable - Run through symbol table looking for type names. If a /// type name is found, emit its declaration... diff --git a/test/CodeGen/CBackend/2008-10-21-PPCLongDoubleConstant.ll b/test/CodeGen/CBackend/2008-10-21-PPCLongDoubleConstant.ll new file mode 100644 index 0000000000..afcac99a76 --- /dev/null +++ b/test/CodeGen/CBackend/2008-10-21-PPCLongDoubleConstant.ll @@ -0,0 +1,29 @@ +; RUN: llvm-as < %s | llc -march=c +; PR2907 +target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f128:64:128" +target triple = "powerpc-apple-darwin9.5" + %"struct.Point<0>" = type { %"struct.Tensor<1,0>" } + %"struct.QGauss2<1>" = type { %"struct.Quadrature<0>" } + %"struct.Quadrature<0>" = type { %struct.Subscriptor, i32, %"struct.std::vector<Point<0>,std::allocator<Point<0> > >", %"struct.std::vector<double,std::allocator<double> >" } + %struct.Subscriptor = type { i32 (...)**, i32, %"struct.std::type_info"* } + %"struct.Tensor<1,0>" = type { [1 x double] } + %"struct.std::_Vector_base<Point<0>,std::allocator<Point<0> > >" = type { %"struct.std::_Vector_base<Point<0>,std::allocator<Point<0> > >::_Vector_impl" } + %"struct.std::_Vector_base<Point<0>,std::allocator<Point<0> > >::_Vector_impl" = type { %"struct.Point<0>"*, %"struct.Point<0>"*, %"struct.Point<0>"* } + %"struct.std::_Vector_base<double,std::allocator<double> >" = type { %"struct.std::_Vector_base<double,std::allocator<double> >::_Vector_impl" } + %"struct.std::_Vector_base<double,std::allocator<double> >::_Vector_impl" = type { double*, double*, double* } + %"struct.std::type_info" = type { i32 (...)**, i8* } + %"struct.std::vector<Point<0>,std::allocator<Point<0> > >" = type { %"struct.std::_Vector_base<Point<0>,std::allocator<Point<0> > >" } + %"struct.std::vector<double,std::allocator<double> >" = type { %"struct.std::_Vector_base<double,std::allocator<double> >" } + +define fastcc void @_ZN6QGaussILi1EEC1Ej(%"struct.QGauss2<1>"* %this, i32 %n) { +entry: + br label %bb4 + +bb4: ; preds = %bb5.split, %bb4, %entry + %0 = fcmp ogt ppc_fp128 0xM00000000000000000000000000000000, select (i1 fcmp olt (ppc_fp128 fpext (double 0x3C447AE147AE147B to ppc_fp128), ppc_fp128 mul (ppc_fp128 0xM00000000000000010000000000000000, ppc_fp128 0xM40140000000000000000000000000000)), ppc_fp128 mul (ppc_fp128 0xM00000000000000010000000000000000, ppc_fp128 0xM40140000000000000000000000000000), ppc_fp128 fpext (double 0x3C447AE147AE147B to ppc_fp128)) ; <i1> [#uses=1] + br i1 %0, label %bb4, label %bb5.split + +bb5.split: ; preds = %bb4 + %1 = getelementptr double* null, i32 0 ; <double*> [#uses=0] + br label %bb4 +} |