forked from OSchip/llvm-project
Fix PR2907 by digging through constant expressions to find FP constants that
are their operands. llvm-svn: 57956
This commit is contained in:
parent
bc55da5768
commit
35b40f8c2f
|
@ -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 &);
|
||||
|
@ -834,10 +838,10 @@ void CWriter::printConstantVector(ConstantVector *CP, bool Static) {
|
|||
static bool isFPCSafeToPrint(const ConstantFP *CFP) {
|
||||
bool ignored;
|
||||
// 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, &ignored);
|
||||
#if HAVE_PRINTF_A && ENABLE_CBE_PRINTF_A
|
||||
char Buffer[100];
|
||||
|
@ -2029,51 +2033,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().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!");
|
||||
}
|
||||
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...
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue