Loading llvm/lib/Target/CBackend/CBackend.cpp +78 −47 Original line number Diff line number Diff line Loading @@ -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"; } Loading Loading @@ -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 &); Loading Loading @@ -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 Loading Loading @@ -2018,30 +2032,48 @@ 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)) { 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().convertToAPInt().getZExtValue(); 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().convertToAPInt(). 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().convertToAPInt(); APInt api = FPC->getValueAPF().bitcastToAPInt(); const uint64_t *p = api.getRawData(); Out << "static const ConstantFP80Ty FPConstant" << FPCounter++ << " = { 0x" Loading @@ -2049,21 +2081,20 @@ void CWriter::printFloatingPointConstants(Function &F) { << "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(); 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 } else { assert(0 && "Unknown float type!"); } Out << '\n'; } /// printSymbolTable - Run through symbol table looking for type names. If a /// type name is found, emit its declaration... /// Loading llvm/test/CodeGen/CBackend/2008-10-21-PPCLongDoubleConstant.ll 0 → 100644 +29 −0 Original line number Diff line number Diff line ; 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 } Loading
llvm/lib/Target/CBackend/CBackend.cpp +78 −47 Original line number Diff line number Diff line Loading @@ -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"; } Loading Loading @@ -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 &); Loading Loading @@ -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 Loading Loading @@ -2018,30 +2032,48 @@ 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)) { 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().convertToAPInt().getZExtValue(); 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().convertToAPInt(). 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().convertToAPInt(); APInt api = FPC->getValueAPF().bitcastToAPInt(); const uint64_t *p = api.getRawData(); Out << "static const ConstantFP80Ty FPConstant" << FPCounter++ << " = { 0x" Loading @@ -2049,21 +2081,20 @@ void CWriter::printFloatingPointConstants(Function &F) { << "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(); 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 } else { assert(0 && "Unknown float type!"); } Out << '\n'; } /// printSymbolTable - Run through symbol table looking for type names. If a /// type name is found, emit its declaration... /// Loading
llvm/test/CodeGen/CBackend/2008-10-21-PPCLongDoubleConstant.ll 0 → 100644 +29 −0 Original line number Diff line number Diff line ; 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 }