diff options
32 files changed, 540 insertions, 437 deletions
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 86b4daadad..b6b3f6346f 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -217,29 +217,13 @@ class ConstantFP : public Constant { APFloat Val; ConstantFP(const ConstantFP &); // DO NOT IMPLEMENT protected: - ConstantFP(const Type *Ty, double V); ConstantFP(const Type *Ty, const APFloat& V); public: /// get() - Static factory methods - Return objects of the specified value - static ConstantFP *get(const Type *Ty, double V); static ConstantFP *get(const Type *Ty, const APFloat& V); /// isValueValidForType - return true if Ty is big enough to represent V. static bool isValueValidForType(const Type *Ty, const APFloat& V); - static bool isValueValidForType(const Type *Ty, double V) { - if (Ty == Type::FloatTy) - return isValueValidForType(Ty, APFloat((float)V)); - else - return isValueValidForType(Ty, APFloat(V)); - } - inline double getValue() const { - if (&Val.getSemantics() == &APFloat::IEEEdouble) - return Val.convertToDouble(); - else if (&Val.getSemantics() == &APFloat::IEEEsingle) - return (double)Val.convertToFloat(); - else - assert(0); - } inline const APFloat& getValueAPF() const { return Val; } /// isNullValue - Return true if this is the value that would be returned by @@ -250,8 +234,11 @@ public: /// isExactlyValue - We don't rely on operator== working on double values, as /// it returns true for things that are clearly not equal, like -0.0 and 0.0. /// As such, this method can be used to do an exact bit-for-bit comparison of - /// two floating point values. + /// two floating point values. The version with a double operand is retained + /// because it's so convenient to write isExactlyValue(2.0), but please use + /// it only for constants. bool isExactlyValue(const APFloat& V) const; + bool isExactlyValue(double V) const { if (&Val.getSemantics() == &APFloat::IEEEdouble) return isExactlyValue(APFloat(V)); diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 70ce34969c..6c828fa004 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -407,8 +407,14 @@ static Constant *ConstantFoldFP(double (*NativeFP)(double), double V, const Type *Ty) { errno = 0; V = NativeFP(V); - if (errno == 0) - return ConstantFP::get(Ty, V); + if (errno == 0) { + if (Ty==Type::FloatTy) + return ConstantFP::get(Ty, APFloat((float)V)); + else if (Ty==Type::DoubleTy) + return ConstantFP::get(Ty, APFloat(V)); + else + assert(0); + } errno = 0; return 0; } @@ -418,14 +424,21 @@ static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double), const Type *Ty) { errno = 0; V = NativeFP(V, W); - if (errno == 0) - return ConstantFP::get(Ty, V); + if (errno == 0) { + if (Ty==Type::FloatTy) + return ConstantFP::get(Ty, APFloat((float)V)); + else if (Ty==Type::DoubleTy) + return ConstantFP::get(Ty, APFloat(V)); + else + assert(0); + } errno = 0; return 0; } /// ConstantFoldCall - Attempt to constant fold a call to the specified function /// with the specified arguments, returning null if unsuccessful. + Constant * llvm::ConstantFoldCall(Function *F, Constant** Operands, unsigned NumOperands) { const ValueName *NameVal = F->getValueName(); @@ -436,7 +449,14 @@ llvm::ConstantFoldCall(Function *F, Constant** Operands, unsigned NumOperands) { const Type *Ty = F->getReturnType(); if (NumOperands == 1) { if (ConstantFP *Op = dyn_cast<ConstantFP>(Operands[0])) { - double V = Op->getValue(); + if (Ty!=Type::FloatTy && Ty!=Type::DoubleTy) + return 0; + /// Currently APFloat versions of these functions do not exist, so we use + /// the host native double versions. Float versions are not called + /// directly but for all these it is true (float)(f((double)arg)) == + /// f(arg). Long double not supported yet. + double V = Ty==Type::FloatTy ? (double)Op->getValueAPF().convertToFloat(): + Op->getValueAPF().convertToDouble(); switch (Str[0]) { case 'a': if (Len == 4 && !strcmp(Str, "acos")) @@ -460,7 +480,7 @@ llvm::ConstantFoldCall(Function *F, Constant** Operands, unsigned NumOperands) { break; case 'f': if (Len == 4 && !strcmp(Str, "fabs")) - return ConstantFP::get(Ty, fabs(V)); + return ConstantFoldFP(fabs, V, Ty); else if (Len == 5 && !strcmp(Str, "floor")) return ConstantFoldFP(floor, V, Ty); break; @@ -472,9 +492,10 @@ llvm::ConstantFoldCall(Function *F, Constant** Operands, unsigned NumOperands) { else if (!strcmp(Str, "llvm.sqrt.f32") || !strcmp(Str, "llvm.sqrt.f64")) { if (V >= -0.0) - return ConstantFP::get(Ty, sqrt(V)); + return ConstantFoldFP(sqrt, V, Ty); else // Undefined - return ConstantFP::get(Ty, 0.0); + return ConstantFP::get(Ty, Ty==Type::FloatTy ? APFloat(0.0f) : + APFloat(0.0)); } break; case 's': @@ -512,9 +533,15 @@ llvm::ConstantFoldCall(Function *F, Constant** Operands, unsigned NumOperands) { } } else if (NumOperands == 2) { if (ConstantFP *Op1 = dyn_cast<ConstantFP>(Operands[0])) { - double Op1V = Op1->getValue(); + double Op1V = Ty==Type::FloatTy ? + (double)Op1->getValueAPF().convertToFloat(): + Op1->getValueAPF().convertToDouble(); if (ConstantFP *Op2 = dyn_cast<ConstantFP>(Operands[1])) { - double Op2V = Op2->getValue(); + if (Ty!=Type::FloatTy && Ty!=Type::DoubleTy) + return 0; + double Op2V = Ty==Type::FloatTy ? + (double)Op2->getValueAPF().convertToFloat(): + Op2->getValueAPF().convertToDouble(); if (Len == 3 && !strcmp(Str, "pow")) { return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty); @@ -525,11 +552,11 @@ llvm::ConstantFoldCall(Function *F, Constant** Operands, unsigned NumOperands) { } } else if (ConstantInt *Op2C = dyn_cast<ConstantInt>(Operands[1])) { if (!strcmp(Str, "llvm.powi.f32")) { - return ConstantFP::get(Ty, std::pow((float)Op1V, - (int)Op2C->getZExtValue())); + return ConstantFP::get(Ty, APFloat((float)std::pow((float)Op1V, + (int)Op2C->getZExtValue()))); } else if (!strcmp(Str, "llvm.powi.f64")) { - return ConstantFP::get(Ty, std::pow((double)Op1V, - (int)Op2C->getZExtValue())); + return ConstantFP::get(Ty, APFloat((double)std::pow((double)Op1V, + (int)Op2C->getZExtValue()))); } } } diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 5bae18cc4c..aaba49eacd 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -485,7 +485,8 @@ SCEVHandle SCEVUnknown::getIntegerSCEV(int Val, const Type *Ty) { if (Val == 0) C = Constant::getNullValue(Ty); else if (Ty->isFloatingPoint()) - C = ConstantFP::get(Ty, Val); + C = ConstantFP::get(Ty, APFloat(Ty==Type::FloatTy ? APFloat::IEEEsingle : + APFloat::IEEEdouble, Val)); else C = ConstantInt::get(Ty, Val); return SCEVUnknown::get(C); diff --git a/lib/AsmParser/Lexer.cpp.cvs b/lib/AsmParser/Lexer.cpp.cvs index 30ddb8fa0f..326bdf0ac7 100644 --- a/lib/AsmParser/Lexer.cpp.cvs +++ b/lib/AsmParser/Lexer.cpp.cvs @@ -2129,15 +2129,17 @@ YY_RULE_SETUP case 145: YY_RULE_SETUP #line 440 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/Lexer.l" -{ llvmAsmlval.FPVal = atof(yytext); return FPVAL; } +{ llvmAsmlval.FPVal = new APFloat(atof(yytext)); return FPVAL; } YY_BREAK case 146: YY_RULE_SETUP #line 441 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/Lexer.l" -{ llvmAsmlval.FPVal = HexToFP(yytext); return FPVAL; } +{ llvmAsmlval.FPVal = new APFloat(HexToFP(yytext)); + return FPVAL; + } YY_BREAK case YY_STATE_EOF(INITIAL): -#line 443 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/Lexer.l" +#line 445 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/Lexer.l" { /* Make sure to free the internal buffers for flex when we are * done reading our input! @@ -2148,20 +2150,20 @@ case YY_STATE_EOF(INITIAL): YY_BREAK case 147: YY_RULE_SETUP -#line 451 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/Lexer.l" +#line 453 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/Lexer.l" { /* Ignore whitespace */ } YY_BREAK case 148: YY_RULE_SETUP -#line 452 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/Lexer.l" +#line 454 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/Lexer.l" { return yytext[0]; } YY_BREAK case 149: YY_RULE_SETUP -#line 454 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/Lexer.l" +#line 456 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/Lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 2165 "Lexer.cpp" +#line 2167 "Lexer.cpp" case YY_END_OF_BUFFER: { @@ -3043,5 +3045,5 @@ int main() return 0; } #endif -#line 454 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/Lexer.l" +#line 456 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/Lexer.l" diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l index 64e6d16eda..390544d8c3 100644 --- a/lib/AsmParser/Lexer.l +++ b/lib/AsmParser/Lexer.l @@ -437,8 +437,10 @@ shufflevector { RET_TOK(OtherOpVal, ShuffleVector, SHUFFLEVECTOR); } return GLOBALVAL_ID; } -{FPConstant} { llvmAsmlval.FPVal = atof(yytext); return FPVAL; } -{HexFPConstant} { llvmAsmlval.FPVal = HexToFP(yytext); return FPVAL; } +{FPConstant} { llvmAsmlval.FPVal = new APFloat(atof(yytext)); return FPVAL; } +{HexFPConstant} { llvmAsmlval.FPVal = new APFloat(HexToFP(yytext)); + return FPVAL; + } <<EOF>> { /* Make sure to free the internal buffers for flex when we are diff --git a/lib/AsmParser/Lexer.l.cvs b/lib/AsmParser/Lexer.l.cvs index 64e6d16eda..390544d8c3 100644 --- a/lib/AsmParser/Lexer.l.cvs +++ b/lib/AsmParser/Lexer.l.cvs @@ -437,8 +437,10 @@ shufflevector { RET_TOK(OtherOpVal, ShuffleVector, SHUFFLEVECTOR); } return GLOBALVAL_ID; } -{FPConstant} { llvmAsmlval.FPVal = atof(yytext); return FPVAL; } -{HexFPConstant} { llvmAsmlval.FPVal = HexToFP(yytext); return FPVAL; } +{FPConstant} { llvmAsmlval.FPVal = new APFloat(atof(yytext)); return FPVAL; } +{HexFPConstant} { llvmAsmlval.FPVal = new APFloat(HexToFP(yytext)); + return FPVAL; + } <<EOF>> { /* Make sure to free the internal buffers for flex when we are diff --git a/lib/AsmParser/ParserInternals.h b/lib/AsmParser/ParserInternals.h index e315902c31..61de652c51 100644 --- a/lib/AsmParser/ParserInternals.h +++ b/lib/AsmParser/ParserInternals.h @@ -22,7 +22,7 @@ #include "llvm/Instructions.h" #include "llvm/Assembly/Parser.h" #include "llvm/ADT/StringExtras.h" - +#include "llvm/ADT/APFloat.h" // Global variables exported from the lexer... @@ -93,10 +93,10 @@ struct ValID { std::string *Name; // If it's a named reference. Memory must be deleted. int64_t ConstPool64; // Constant pool reference. This is the value uint64_t UConstPool64;// Unsigned constant pool reference. - double ConstPoolFP; // Floating point constant pool reference + APFloat *ConstPoolFP; // Floating point constant pool reference Constant *ConstantValue; // Fully resolved constant for ConstantVal case. InlineAsmDescriptor *IAD; - }; + }; static ValID createLocalID(unsigned Num) { ValID D; D.Type = LocalID; D.Num = Num; return D; @@ -119,7 +119,7 @@ struct ValID { ValID D; D.Type = ConstUIntVal; D.UConstPool64 = Val; return D; } - static ValID create(double Val) { + static ValID create(APFloat *Val) { ValID D; D.Type = ConstFPVal; D.ConstPoolFP = Val; return D; } @@ -168,7 +168,7 @@ struct ValID { case GlobalID : return '@' + utostr(Num); case LocalName : return *Name; case GlobalName : return *Name; - case ConstFPVal : return ftostr(ConstPoolFP); + case ConstFPVal : return ftostr(*ConstPoolFP); case ConstNullVal : return "null"; case ConstUndefVal : return "undef"; case ConstZeroVal : return "zeroinitializer"; @@ -194,7 +194,8 @@ struct ValID { case GlobalName: return *Name < *V.Name; case ConstSIntVal: return ConstPool64 < V.ConstPool64; case ConstUIntVal: return UConstPool64 < V.UConstPool64; - case ConstFPVal: return ConstPoolFP < V.ConstPoolFP; + case ConstFPVal: return ConstPoolFP->compare(*V.ConstPoolFP) == + APFloat::cmpLessThan; case ConstNullVal: return false; case ConstUndefVal: return false; case ConstZeroVal: return false; @@ -212,7 +213,8 @@ struct ValID { case GlobalName: return *Name == *(V.Name); case ConstSIntVal: return ConstPool64 == V.ConstPool64; case ConstUIntVal: return UConstPool64 == V.UConstPool64; - case ConstFPVal: return ConstPoolFP == V.ConstPoolFP; + case ConstFPVal: return ConstPoolFP->compare(*V.ConstPoolFP) == + APFloat::cmpEqual; case ConstantVal: return ConstantValue == V.ConstantValue; case ConstNullVal: return true; case ConstUndefVal: return true; diff --git a/lib/AsmParser/llvmAsmParser.h.cvs b/lib/AsmParser/llvmAsmParser.h.cvs index 353388b01a..feb3ff6d30 100644 --- a/lib/AsmParser/llvmAsmParser.h.cvs +++ b/lib/AsmParser/llvmAsmParser.h.cvs @@ -355,7 +355,7 @@ typedef union YYSTYPE { uint64_t UInt64Val; int SIntVal; unsigned UIntVal; - double FPVal; + llvm::APFloat *FPVal; bool BoolVal; std::string *StrVal; // This memory must be deleted diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 93f7a085bc..83dfa31f03 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -412,11 +412,15 @@ static Value *getExistingVal(const Type *Ty, const ValID &D) { } case ValID::ConstFPVal: // Is it a floating point const pool reference? - if (!ConstantFP::isValueValidForType(Ty, D.ConstPoolFP)) { + if (!ConstantFP::isValueValidForType(Ty, *D.ConstPoolFP)) { GenerateError("FP constant invalid for type"); return 0; } - return ConstantFP::get(Ty, D.ConstPoolFP); + // Lexer has no type info, so builds all FP constants as double. + // Fix this here. + if (Ty==Type::FloatTy) + D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven); + return ConstantFP::get(Ty, *D.ConstPoolFP); case ValID::ConstNullVal: // Is it a null value? if (!isa<PointerType>(Ty)) { @@ -992,7 +996,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { uint64_t UInt64Val; int SIntVal; unsigned UIntVal; - double FPVal; + llvm::APFloat *FPVal; bool BoolVal; std::string *StrVal; // This memory must be deleted @@ -1862,9 +1866,13 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr CHECK_FOR_ERROR } | FPType FPVAL { // Float & Double constants - if (!ConstantFP::isValueValidForType($1, $2)) + if (!ConstantFP::isValueValidForType($1, *$2)) GEN_ERROR("Floating point constant invalid for type"); - $$ = ConstantFP::get($1, $2); + // Lexer has no type info, so builds all FP constants as double. + // Fix this here. + if ($1==Type::FloatTy) + $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven); + $$ = ConstantFP::get($1, *$2); CHECK_FOR_ERROR }; diff --git a/lib/AsmParser/llvmAsmParser.y.cvs b/lib/AsmParser/llvmAsmParser.y.cvs index 93f7a085bc..83dfa31f03 100644 --- a/lib/AsmParser/llvmAsmParser.y.cvs +++ b/lib/AsmParser/llvmAsmParser.y.cvs @@ -412,11 +412,15 @@ static Value *getExistingVal(const Type *Ty, const ValID &D) { } case ValID::ConstFPVal: // Is it a floating point const pool reference? - if (!ConstantFP::isValueValidForType(Ty, D.ConstPoolFP)) { + if (!ConstantFP::isValueValidForType(Ty, *D.ConstPoolFP)) { GenerateError("FP constant invalid for type"); return 0; } - return ConstantFP::get(Ty, D.ConstPoolFP); + // Lexer has no type info, so builds all FP constants as double. + // Fix this here. + if (Ty==Type::FloatTy) + D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven); + return ConstantFP::get(Ty, *D.ConstPoolFP); case ValID::ConstNullVal: // Is it a null value? if (!isa<PointerType>(Ty)) { @@ -992,7 +996,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { uint64_t UInt64Val; int SIntVal; unsigned UIntVal; - double FPVal; + llvm::APFloat *FPVal; bool BoolVal; std::string *StrVal; // This memory must be deleted @@ -1862,9 +1866,13 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr CHECK_FOR_ERROR } | FPType FPVAL { // Float & Double constants - if (!ConstantFP::isValueValidForType($1, $2)) + if (!ConstantFP::isValueValidForType($1, *$2)) GEN_ERROR("Floating point constant invalid for type"); - $$ = ConstantFP::get($1, $2); + // Lexer has no type info, so builds all FP constants as double. + // Fix this here. + if ($1==Type::FloatTy) + $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven); + $$ = ConstantFP::get($1, *$2); CHECK_FOR_ERROR }; diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 6ad1fd595b..fcf2e510f9 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -626,13 +626,16 @@ bool BitcodeReader::ParseConstants() { if (Record.empty()) return Error("Invalid FLOAT record"); if (CurTy == Type::FloatTy) - V = ConstantFP::get(CurTy, BitsToFloat(Record[0])); + V = ConstantFP::get(CurTy, APFloat((float)BitsToDouble(Record[0]))); else if (CurTy == Type::DoubleTy) - V = ConstantFP::get(CurTy, BitsToDouble(Record[0])); - // FIXME: Make long double constants work. - else if (CurTy == Type::X86_FP80Ty || - CurTy == Type::FP128Ty || CurTy == Type::PPC_FP128Ty) - assert(0 && "Long double constants not handled yet."); + V = ConstantFP::get(CurTy, APFloat(BitsToDouble(Record[0]))); + // FIXME: Make long double constants work. BitsToDouble does not make it. + else if (CurTy == Type::X86_FP80Ty) + V = ConstantFP::get(CurTy, APFloat(BitsToDouble(Record[0]))); + else if (CurTy == Type::FP128Ty) + V = ConstantFP::get(CurTy, APFloat(BitsToDouble(Record[0]))); + else if (CurTy == Type::PPC_FP128Ty) + assert(0 && "PowerPC long double constants not handled yet."); else V = UndefValue::get(CurTy); break; diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 17c14f0a0d..ab3d9834d1 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -527,9 +527,10 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, Code = bitc::CST_CODE_FLOAT; const Type *Ty = CFP->getType(); if (Ty == Type::FloatTy) { - Record.push_back(FloatToBits((float)CFP->getValue())); + Record.push_back(DoubleToBits((double)CFP->getValueAPF(). + convertToFloat())); } else if (Ty == Type::DoubleTy) { - Record.push_back(DoubleToBits((double)CFP->getValue())); + Record.push_back(DoubleToBits(CFP->getValueAPF().convertToDouble())); // FIXME: make long double constants work. } else if (Ty == Type::X86_FP80Ty || Ty == Type::FP128Ty || Ty == Type::PPC_FP128Ty) { diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index fa6f5691fc..e80afd40ee 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -829,8 +829,8 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) { } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) { // FP Constants are printed as integer constants to avoid losing // precision... - double Val = CFP->getValue(); if (CFP->getType() == Type::DoubleTy) { + double Val = CFP->getValueAPF().convertToDouble(); if (TAI->getData64bitsDirective()) O << TAI->getData64bitsDirective() << DoubleToBits(Val) << "\t" << TAI->getCommentString() << " double value: " << Val << "\n"; @@ -851,6 +851,7 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) { } return; } else { + float Val = CFP->getValueAPF().convertToFloat(); O << TAI->getData32bitsDirective() << FloatToBits(Val) << "\t" << TAI->getCommentString() << " float " << Val << "\n"; return; diff --git a/lib/CodeGen/MachOWriter.cpp b/lib/CodeGen/MachOWriter.cpp index 36060e150e..af2555d3ee 100644 --- a/lib/CodeGen/MachOWriter.cpp +++ b/lib/CodeGen/MachOWriter.cpp @@ -861,7 +861,8 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset, break; } case Type::FloatTyID: { - uint64_t val = FloatToBits(cast<ConstantFP>(PC)->getValue()); + uint64_t val = FloatToBits(cast<ConstantFP>(PC)-> + getValueAPF().convertToFloat()); if (TD->isBigEndian()) val = ByteSwap_32(val); ptr[0] = val; @@ -871,7 +872,8 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset, break; } case Type::DoubleTyID: { - uint64_t val = DoubleToBits(cast<ConstantFP>(PC)->getValue()); + uint64_t val = DoubleToBits(cast<ConstantFP>(PC)-> + getValueAPF().convertToDouble()); if (TD->isBigEndian()) val = ByteSwap_64(val); ptr[0] = val; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index a695048a5a..d1e9365274 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -840,7 +840,7 @@ SDOperand SelectionDAGLowering::getValue(const Value *V) { return N = DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size()); } else if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) { - return N = DAG.getConstantFP(CFP->getValue(), VT); + return N = DAG.getConstantFP(CFP->getValueAPF(), VT); } else if (const VectorType *PTy = dyn_cast<VectorType>(VTy)) { unsigned NumElements = PTy->getNumElements(); MVT::ValueType PVT = TLI.getValueType(PTy->getElementType()); @@ -2003,7 +2003,8 @@ void SelectionDAGLowering::visitSub(User &I) { const Type *ElTy = DestTy->getElementType(); if (ElTy->isFloatingPoint()) { unsigned VL = DestTy->getNumElements(); - std::vector<Constant*> NZ(VL, ConstantFP::get(ElTy, -0.0)); + std::vector<Constant*> NZ(VL, ConstantFP::get(ElTy, + ElTy==Type::FloatTy ? APFloat(-0.0f) : APFloat(-0.0))); Constant *CNZ = ConstantVector::get(&NZ[0], NZ.size()); if (CV == CNZ) { SDOperand Op2 = getValue(I.getOperand(1)); diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 325ab8af52..fb9ff371d5 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -525,10 +525,10 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { GenericValue Result; switch (C->getType()->getTypeID()) { case Type::FloatTyID: - Result.FloatVal = (float)cast<ConstantFP>(C)->getValue(); + Result.FloatVal = cast<ConstantFP>(C)->getValueAPF().convertToFloat(); break; case Type::DoubleTyID: - Result.DoubleVal = (double)cast<ConstantFP>(C)->getValue(); + Result.DoubleVal = cast<ConstantFP>(C)->getValueAPF().convertToDouble(); break; case Type::IntegerTyID: Result.IntVal = cast<ConstantInt>(C)->getValue(); diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp index 766d62ce19..848786f314 100644 --- a/lib/ExecutionEngine/JIT/JIT.cpp +++ b/lib/ExecutionEngine/JIT/JIT.cpp @@ -206,8 +206,10 @@ GenericValue JIT::runFunction(Function *F, switch (ArgTy->getTypeID()) { default: assert(0 && "Unknown argument type for function call!"); case Type::IntegerTyID: C = ConstantInt::get(AV.IntVal); break; - case Type::FloatTyID: C = ConstantFP ::get(ArgTy, AV.FloatVal); break; - case Type::DoubleTyID: C = ConstantFP ::get(ArgTy, AV.DoubleVal); break; + case Type::FloatTyID: C = ConstantFP ::get(ArgTy, APFloat(AV.FloatVal)); + break; + case Type::DoubleTyID: C = ConstantFP ::get(ArgTy, APFloat(AV.DoubleVal)); + break; case Type::PointerTyID: void *ArgPtr = GVTOP(AV); if (sizeof(void*) == 4) { diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index b0c76c8e8e..ff95e90dc7 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -604,17 +604,19 @@ void CWriter::printConstantVector(ConstantVector *CP) { // only deal in IEEE FP). // static bool isFPCSafeToPrint(const ConstantFP *CFP) { + APFloat APF = APFloat(CFP->getValueAPF()); // copy + if (CFP->getType()==Type::FloatTy) + APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven); #if HAVE_PRINTF_A && ENABLE_CBE_PRINTF_A char Buffer[100]; - sprintf(Buffer, "%a", CFP->getValue()); - + sprintf(Buffer, "%a", APF.convertToDouble()); if (!strncmp(Buffer, "0x", 2) || !strncmp(Buffer, "-0x", 3) || !strncmp(Buffer, "+0x", 3)) - return atof(Buffer) == CFP->getValue(); + return APF.bitwiseIsEqual(APFloat(atof(Buffer))); return false; #else - std::string StrVal = ftostr(CFP->getValue()); + std::string StrVal = ftostr(APF); while (StrVal[0] == ' ') StrVal.erase(StrVal.begin()); @@ -625,7 +627,7 @@ static bool isFPCSafeToPrint(const ConstantFP *CFP) { ((StrVal[0] == '-' || StrVal[0] == '+') && (StrVal[1] >= '0' && StrVal[1] <= '9'))) // Reparse stringized version! - return atof(StrVal.c_str()) == CFP->getValue(); + return APF.bitwiseIsEqual(APFloat(atof(StrVal.c_str()))); return false; #endif } @@ -882,9 +884,13 @@ void CWriter::printConstant(Constant *CPV) { Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" : "double") << "*)&FPConstant" << I->second << ')'; } else { - if (IsNAN(FPC->getValue())) { + double V = FPC->getType() == Type::FloatTy ? + FPC->getValueAPF().convertToFloat() : + FPC->getValueAPF().convertToDouble(); + if (IsNAN(V)) { // The value is NaN + // FIXME the actual NaN bits should be emitted. // The prefix for a quiet NaN is 0x7FF8. For a signalling NaN, // it's 0x7ff4. const unsigned long QuietNaN = 0x7ff8UL; @@ -893,7 +899,7 @@ void CWriter::printConstant(Constant *CPV) { // We need to grab the first part of the FP # char Buffer[100]; |