diff options
Diffstat (limited to 'lib')
24 files changed, 295 insertions, 206 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 70ce349..6c828fa 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 5bae18c..aaba49e 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 30ddb8f..326bdf0 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 64e6d16..390544d 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 64e6d16..390544d 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 e315902..61de652 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 353388b..feb3ff6 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 93f7a08..83dfa31 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 93f7a08..83dfa31 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 6ad1fd5..fcf2e51 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 17c14f0..ab3d983 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 fa6f569..e80afd4 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 36060e1..af2555d 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 a695048..d1e9365 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 325ab8a..fb9ff37 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 766d62c..848786f 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 b0c76c8..ff95e90 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]; - uint64_t ll = DoubleToBits(FPC->getValue()); + uint64_t ll = DoubleToBits(V); sprintf(Buffer, "0x%llx", static_cast<long long>(ll)); std::string Num(&Buffer[0], &Buffer[6]); @@ -905,9 +911,9 @@ void CWriter::printConstant(Constant *CPV) { else Out << "LLVM_NAN" << (Val == QuietNaN ? "" : "S") << "(\"" << Buffer << "\") /*nan*/ "; - } else if (IsInf(FPC->getValue())) { + } else if (IsInf(V)) { // The value is Inf - if (FPC->getValue() < 0) Out << '-'; + if (V < 0) Out << '-'; Out << "LLVM_INF" << (FPC->getType() == Type::FloatTy ? "F" : "") << " /*inf*/ "; } else { @@ -915,12 +921,12 @@ void CWriter::printConstant(Constant *CPV) { #if HAVE_PRINTF_A && ENABLE_CBE_PRINTF_A // Print out the constant as a floating point number. char Buffer[100]; - sprintf(Buffer, "%a", FPC->getValue()); + sprintf(Buffer, "%a", V); Num = Buffer; #else - Num = ftostr(FPC->getValue()); + Num = ftostr(FPC->getValueAPF()); #endif - Out << Num; + Out << Num; } } break; @@ -1715,15 +1721,15 @@ void CWriter::printFloatingPointConstants(Function &F) { if (const ConstantFP *FPC = dyn_cast<ConstantFP>(*I)) if (!isFPCSafeToPrint(FPC) && // Do not put in FPConstantMap if safe. !FPConstantMap.count(FPC)) { - double Val = FPC->getValue(); - FPConstantMap[FPC] = FPCounter; // Number the FP constants if (FPC->getType() == Type::DoubleTy) { + double Val = FPC->getValueAPF().convertToDouble(); Out << "static const ConstantDoubleTy FPConstant" << FPCounter++ << " = 0x" << std::hex << DoubleToBits(Val) << std::dec << "ULL; /* " << Val << " */\n"; } else if (FPC->getType() == Type::FloatTy) { + float Val = FPC->getValueAPF().convertToFloat(); Out << "static const ConstantFloatTy FPConstant" << FPCounter++ << " = 0x" << std::hex << FloatToBits(Val) << std::dec << "U; /* " << Val << " */\n"; diff --git a/lib/Target/MSIL/MSILWriter.cpp b/lib/Target/MSIL/MSILWriter.cpp index 5859adf..7178970 100644 --- a/lib/Target/MSIL/MSILWriter.cpp +++ b/lib/Target/MSIL/MSILWriter.cpp @@ -428,10 +428,10 @@ void MSILWriter::printConstLoad(const Constant* C) { uint64_t X; unsigned Size; if (FP->getType()->getTypeID()==Type::FloatTyID) { - X = FloatToBits(FP->getValue()); + X = FloatToBits(FP->getValueAPF().convertToFloat()); Size = 4; } else { - X = DoubleToBits(FP->getValue()); + X = DoubleToBits(FP->getValueAPF().convertToDouble()); Size = 8; } Out << "\tldc.r" << Size << "\t( " << utohexstr(X) << ')'; @@ -1472,9 +1472,11 @@ void MSILWriter::printStaticConstant(const Constant* C, uint64_t& Offset) { TySize = TD->getTypeSize(Ty); const ConstantFP* FP = cast<ConstantFP>(C); if (Ty->getTypeID() == Type::FloatTyID) - Out << "int32 (" << FloatToBits(FP->getValue()) << ')'; + Out << "int32 (" << + FloatToBits(FP->getValueAPF().convertToFloat()) << ')'; else - Out << "int64 (" << DoubleToBits(FP->getValue()) << ')'; + Out << "int64 (" << + DoubleToBits(FP->getValueAPF().convertToDouble()) << ')'; break; } case Type::ArrayTyID: diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 8cfd5f9..22b282b 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -3412,11 +3412,11 @@ SDOperand X86TargetLowering::LowerFABS(SDOperand Op, SelectionDAG &DAG) { const Type *OpNTy = MVT::getTypeForValueType(EltVT); std::vector<Constant*> CV; if (EltVT == MVT::f64) { - Constant *C = ConstantFP::get(OpNTy, BitsToDouble(~(1ULL << 63))); + Constant *C = ConstantFP::get(OpNTy, APFloat(BitsToDouble(~(1ULL << 63)))); CV.push_back(C); CV.push_back(C); } else { - Constant *C = ConstantFP::get(OpNTy, BitsToFloat(~(1U << 31))); + Constant *C = ConstantFP::get(OpNTy, APFloat(BitsToFloat(~(1U << 31)))); CV.push_back(C); CV.push_back(C); CV.push_back(C); @@ -3440,11 +3440,11 @@ SDOperand X86TargetLowering::LowerFNEG(SDOperand Op, SelectionDAG &DAG) { const Type *OpNTy = MVT::getTypeForValueType(EltVT); std::vector<Constant*> CV; if (EltVT == MVT::f64) { - Constant *C = ConstantFP::get(OpNTy, BitsToDouble(1ULL << 63)); + Constant *C = ConstantFP::get(OpNTy, APFloat(BitsToDouble(1ULL << 63))); CV.push_back(C); CV.push_back(C); } else { - Constant *C = ConstantFP::get(OpNTy, BitsToFloat(1U << 31)); + Constant *C = ConstantFP::get(OpNTy, APFloat(BitsToFloat(1U << 31))); CV.push_back(C); CV.push_back(C); CV.push_back(C); @@ -3475,18 +3475,19 @@ SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) { if (MVT::getSizeInBits(SrcVT) < MVT::getSizeInBits(VT)) { Op1 = DAG.getNode(ISD::FP_EXTEND, VT, Op1); SrcVT = VT; + SrcTy = MVT::getTypeForValueType(SrcVT); } // First get the sign bit of second operand. std::vector<Constant*> CV; if (SrcVT == MVT::f64) { - CV.push_back(ConstantFP::get(SrcTy, BitsToDouble(1ULL << 63))); - CV.push_back(ConstantFP::get(SrcTy, 0.0)); + CV.push_back(ConstantFP::get(SrcTy, APFloat(BitsToDouble(1ULL << 63)))); + CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0))); } else { - CV.push_back(ConstantFP::get(SrcTy, BitsToFloat(1U << 31))); - CV.push_back(ConstantFP::get(SrcTy, 0.0)); - CV.push_back(ConstantFP::get(SrcTy, 0.0)); - CV.push_back(ConstantFP::get(SrcTy, 0.0)); + CV.push_back(ConstantFP::get(SrcTy, APFloat(BitsToFloat(1U << 31)))); + CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0f))); + CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0f))); + CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0f))); } Constant *C = ConstantVector::get(CV); SDOperand CPIdx = DAG.getConstantPool(C, getPointerTy(), 4); @@ -3508,13 +3509,13 @@ SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) { // Clear first operand sign bit. CV.clear(); if (VT == MVT::f64) { - CV.push_back(ConstantFP::get(SrcTy, BitsToDouble(~(1ULL << 63)))); - CV.push_back(ConstantFP::get(SrcTy, 0.0)); + CV.push_back(ConstantFP::get(SrcTy, APFloat(BitsToDouble(~(1ULL << 63))))); + CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0))); } else { - CV.push_back(ConstantFP::get(SrcTy, BitsToFloat(~(1U << 31)))); - CV.push_back(ConstantFP::get(SrcTy, 0.0)); - CV.push_back(ConstantFP::get(SrcTy, 0.0)); - CV.push_back(ConstantFP::get(SrcTy, 0.0)); + CV.push_back(ConstantFP::get(SrcTy, APFloat(BitsToFloat(~(1U << 31))))); + CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0f))); + CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0f))); + CV.push_back(ConstantFP::get(SrcTy, APFloat(0.0f))); } C = ConstantVector::get(CV); CPIdx = DAG.getConstantPool(C, getPointerTy(), 4); diff --git a/lib/Transforms/IPO/SimplifyLibCalls.cpp b/lib/Transforms/IPO/SimplifyLibCalls.cpp index 5925f58..01d3c9f 100644 --- a/lib/Transforms/IPO/SimplifyLibCalls.cpp +++ b/lib/Transforms/IPO/SimplifyLibCalls.cpp @@ -1118,27 +1118,32 @@ public: Value* base = ci->getOperand(1); Value* expn = ci->getOperand(2); if (ConstantFP *Op1 = dyn_cast<ConstantFP>(base)) { - double Op1V = Op1->getValue(); - if (Op1V == 1.0) // pow(1.0,x) -> 1.0 - return ReplaceCallWith(ci, ConstantFP::get(Ty, 1.0)); + if (Ty!=Type::FloatTy && Ty!=Type::DoubleTy) + return false; // FIXME long double not yet supported + if (Op1->isExactlyValue(1.0)) // pow(1.0,x) -> 1.0 + return ReplaceCallWith(ci, ConstantFP::get(Ty, + Ty==Type::FloatTy ? APFloat(1.0f) : APFloat(1.0))); } else if (ConstantFP* Op2 = dyn_cast<ConstantFP>(expn)) { - double Op2V = Op2->getValue(); - if (Op2V == 0.0) { + if (Ty!=Type::FloatTy && Ty!=Type::DoubleTy) + return false; // FIXME long double not yet supported + if (Op2->getValueAPF().isZero()) { // pow(x,0.0) -> 1.0 - return ReplaceCallWith(ci, ConstantFP::get(Ty,1.0)); - } else if (Op2V == 0.5) { + return ReplaceCallWith(ci, ConstantFP::get(Ty, + Ty==Type::FloatTy ? APFloat(1.0f) : APFloat(1.0))); + } else if (Op2->isExactlyValue(0.5)) { // pow(x,0.5) -> sqrt(x) CallInst* sqrt_inst = new CallInst(SLC.get_sqrt(), base, ci->getName()+".pow",ci); return ReplaceCallWith(ci, sqrt_inst); - } else if (Op2V == 1.0) { + } else if (Op2->isExactlyValue(1.0)) { // pow(x,1.0) -> x return ReplaceCallWith(ci, base); - } else if (Op2V == -1.0) { + } else if (Op2->isExactlyValue(-1.0)) { // pow(x,-1.0) -> 1.0/x Value *div_inst = - BinaryOperator::createFDiv(ConstantFP::get(Ty, 1.0), base, - ci->getName()+".pow", ci); + BinaryOperator::createFDiv(ConstantFP::get(Ty, + Ty==Type::FloatTy ? APFloat(1.0f) : APFloat(1.0)), + base, ci->getName()+".pow", ci); return ReplaceCallWith(ci, div_inst); } } diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 4902fb7..26df555 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -2348,7 +2348,7 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) { // "In IEEE floating point, x*1 is not equivalent to x for nans. However, // ANSI says we can drop signals, so we can do this anyway." (from GCC) - if (Op1F->getValue() == 1.0) + if (Op1F->isExactlyValue(1.0)) return ReplaceInstUsesWith(I, Op0); // Eliminate 'mul double %X, 1.0' } diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 9286e15..a7b1239 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -486,7 +486,10 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, // make sure that we only output it in exponential format if we can parse // the value back and get the same value. // - std::string StrVal = ftostr(CFP->getValue()); + bool isDouble = &CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble; + double Val = (isDouble) ? CFP->getValueAPF().convertToDouble() : + CFP->getValueAPF().convertToFloat(); + std::string StrVal = ftostr(CFP->getValueAPF()); // Check to make sure that the stringized number is not some string like // "Inf" or NaN, that atof will accept, but the lexer will not. Check that @@ -496,7 +499,7 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, ((StrVal[0] == '-' || StrVal[0] == '+') && (StrVal[1] >= '0' && StrVal[1] <= '9'))) // Reparse stringized version! - if (atof(StrVal.c_str()) == CFP->getValue()) { + if (atof(StrVal.c_str()) == Val) { Out << StrVal; return; } @@ -505,7 +508,7 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, // output the string in hexadecimal format! assert(sizeof(double) == sizeof(uint64_t) && "assuming that double is 64 bits!"); - Out << "0x" << utohexstr(DoubleToBits(CFP->getValue())); + Out << "0x" << utohexstr(DoubleToBits(Val)); } else if (isa<ConstantAggregateZero>(CV)) { Out << "zeroinitializer"; diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index fb2e65f..5686a0e 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -68,7 +68,7 @@ static Constant *CastConstantVector(ConstantVector *CV, for (unsigned i = 0; i != SrcNumElts; ++i) { ConstantInt *CI = cast<ConstantInt>(CV->getOperand(i)); double V = CI->getValue().bitsToDouble(); - Result.push_back(ConstantFP::get(Type::DoubleTy, V)); + Result.push_back(ConstantFP::get(Type::DoubleTy, APFloat(V))); } return ConstantVector::get(Result); } @@ -76,7 +76,7 @@ static Constant *CastConstantVector(ConstantVector *CV, for (unsigned i = 0; i != SrcNumElts; ++i) { ConstantInt *CI = cast<ConstantInt>(CV->getOperand(i)); float V = CI->getValue().bitsToFloat(); - Result.push_back(ConstantFP::get(Type::FloatTy, V)); + Result.push_back(ConstantFP::get(Type::FloatTy, APFloat(V))); } return ConstantVector::get(Result); } @@ -87,7 +87,8 @@ static Constant *CastConstantVector(ConstantVector *CV, if (SrcEltTy->getTypeID() == Type::DoubleTyID) { for (unsigned i = 0; i != SrcNumElts; ++i) { uint64_t V = - DoubleToBits(cast<ConstantFP>(CV->getOperand(i))->getValue()); + DoubleToBits(cast<ConstantFP>(CV->getOperand(i))-> + getValueAPF().convertToDouble()); Constant *C = ConstantInt::get(Type::Int64Ty, V); Result.push_back(ConstantExpr::getBitCast(C, DstEltTy )); } @@ -96,7 +97,8 @@ static Constant *CastConstantVector(ConstantVector *CV, assert(SrcEltTy->getTypeID() == Type::FloatTyID); for (unsigned i = 0; i != SrcNumElts; ++i) { - uint32_t V = FloatToBits(cast<ConstantFP>(CV->getOperand(i))->getValue()); + uint32_t V = FloatToBits(cast<ConstantFP>(CV->getOperand(i))-> + getValueAPF().convertToFloat()); Constant *C = ConstantInt::get(Type::Int32Ty, V); Result.push_back(ConstantExpr::getBitCast(C, DstEltTy)); } @@ -175,20 +177,31 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, switch (opc) { case Instruction::FPTrunc: case Instruction::FPExt: - if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) - return ConstantFP::get(DestTy, FPC->getValue()); + if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) { + APFloat Val = FPC->getValueAPF(); + Val.convert(DestTy==Type::FloatTy ? APFloat::IEEEsingle : + APFloat::IEEEdouble, + APFloat::rmNearestTiesToEven); + return ConstantFP::get(DestTy, Val); + } return 0; // Can't fold. case Instruction::FPToUI: if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) { + APFloat V = FPC->getValueAPF(); + bool isDouble = &V.getSemantics()==&APFloat::IEEEdouble; uint32_t DestBitWidth = cast<IntegerType>(DestTy)->getBitWidth(); - APInt Val(APIntOps::RoundDoubleToAPInt(FPC->getValue(), DestBitWidth)); + APInt Val(APIntOps::RoundDoubleToAPInt(isDouble ? V.convertToDouble() : + (double)V.convertToFloat(), DestBitWidth)); return ConstantInt::get(Val); } return 0; // Can't fold. case Instruction::FPToSI: if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) { + APFloat V = FPC->getValueAPF(); + bool isDouble = &V.getSemantics()==&APFloat::IEEEdouble; uint32_t DestBitWidth = cast<IntegerType>(DestTy)->getBitWidth(); - APInt Val(APIntOps::RoundDoubleToAPInt(FPC->getValue(), DestBitWidth)); + APInt Val(APIntOps::RoundDoubleToAPInt(isDouble ? V.convertToDouble() : + (double)V.convertToFloat(), DestBitWidth)); return ConstantInt::get(Val); } return 0; // Can't fold. @@ -201,12 +214,22 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, return ConstantInt::get(DestTy, 0); return 0; // Other pointer types cannot be casted case Instruction::UIToFP: - if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) - return ConstantFP::get(DestTy, CI->getValue().roundToDouble()); + if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { + if (DestTy==Type::FloatTy) + return ConstantFP::get(DestTy, + APFloat((float)CI->getValue().roundToDouble())); + else + return ConstantFP::get(DestTy, APFloat(CI->getValue().roundToDouble())); + } return 0; case Instruction::SIToFP: - if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) - return ConstantFP::get(DestTy, CI->getValue().signedRoundToDouble()); + if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { + double d = CI->getValue().signedRoundToDouble(); + if (DestTy==Type::FloatTy) + return ConstantFP::get(DestTy, APFloat((float)d)); + else + return ConstantFP::get(DestTy, APFloat(d)); + } return 0; case Instruction::ZExt: if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { @@ -309,9 +332,9 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, if (DestTy->isFloatingPoint()) { if (DestTy == Type::FloatTy) - return ConstantFP::get(DestTy, CI->getValue().bitsToFloat()); + return ConstantFP::get(DestTy, APFloat(CI->getValue().bitsToFloat())); assert(DestTy == Type::DoubleTy && "Unknown FP type!"); - return ConstantFP::get(DestTy, CI->getValue().bitsToDouble()); + return ConstantFP::get(DestTy, APFloat(CI->getValue().bitsToDouble())); } // Otherwise, can't fold this (vector?) return 0; @@ -322,11 +345,13 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, // FP -> Integral. if (DestTy == Type::Int32Ty) { APInt Val(32, 0); - return ConstantInt::get(Val.floatToBits(FP->getValue())); + return ConstantInt::get(Val.floatToBits(FP-> + getValueAPF().convertToFloat())); } else { assert(DestTy == Type::Int64Ty && "only support f32/f64 for now!"); APInt Val(64, 0); - return ConstantInt::get(Val.doubleToBits(FP->getValue())); + return ConstantInt::get(Val.doubleToBits(FP-> + getValueAPF().convertToDouble())); } } return 0; @@ -660,39 +685,50 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, } } else if (const ConstantFP *CFP1 = dyn_cast<ConstantFP>(C1)) { if (const ConstantFP *CFP2 = dyn_cast<ConstantFP>(C2)) { - double C1Val = CFP1->getValue(); - double C2Val = CFP2->getValue(); + APFloat C1V = CFP1->getValueAPF(); + APFloat C2V = CFP2->getValueAPF(); + APFloat C3V = C1V; // copy for modification + bool isDouble = CFP1->getType()==Type::DoubleTy; switch (Opcode) { default: break; - case Instruction::Add: - return ConstantFP::get(CFP1->getType(), C1Val + C2Val); + case Instruction::Add: + (void)C3V.add(C2V, APFloat::rmNearestTiesToEven); + return ConstantFP::get(CFP1->getType(), C3V); case Instruction::Sub: - return ConstantFP::get(CFP1->getType(), C1Val - C2Val); - case Instruction::Mul: - return ConstantFP::get(CFP1->getType(), C1Val * C2Val); + (void)C3V.subtract(C2V, APFloat::rmNearestTiesToEven); + return ConstantFP::get(CFP1->getType(), C3V); + case Instruction::Mul: + (void)C3V.multiply(C2V, APFloat::rmNearestTiesToEven); + return ConstantFP::get(CFP1->getType(), C3V); case Instruction::FDiv: - if (CFP2->isExactlyValue(0.0) || CFP2->isExactlyValue(-0.0)) - if (CFP1->isExactlyValue(0.0) || CFP1->isExactlyValue(-0.0)) + // FIXME better to look at the return code + if (C2V.isZero()) + if (C1V.isZero()) // IEEE 754, Section 7.1, #4 - return ConstantFP::get(CFP1->getType(), - std::numeric_limits<double>::quiet_NaN()); - else if (CFP2->isExactlyValue(-0.0) || C1Val < 0.0) + return ConstantFP::get(CFP1->getType(), isDouble ? + APFloat(std::numeric_limits<double>::quiet_NaN()) : + APFloat(std::numeric_limits<float>::quiet_NaN())); + else if (C2V.isNegZero() || C1V.isNegative()) // IEEE 754, Section 7.2, negative infinity case - return ConstantFP::get(CFP1->getType(), - -std::numeric_limits<double>::infinity()); + return ConstantFP::get(CFP1->getType(), isDouble ? + APFloat(-std::numeric_limits<double>::infinity()) : + APFloat(-std::numeric_limits<float>::infinity())); else // IEEE 754, Section 7.2, positive infinity case - return ConstantFP::get(CFP1->getType(), - std::numeric_limits<double>::infinity()); - return ConstantFP::get(CFP1->getType(), C1Val / C2Val); + return ConstantFP::get(CFP1->getType(), isDouble ? + APFloat(std::numeric_limits<double>::infinity()) : + APFloat(std::numeric_limits<float>::infinity())); + (void)C3V.divide(C2V, APFloat::rmNearestTiesToEven); + return ConstantFP::get(CFP1->getType(), C3V); case Instruction::FRem: - if (CFP2->isExactlyValue(0.0) || CFP2->isExactlyValue(-0.0)) + if (C2V.isZero()) // IEEE 754, Section 7.1, #5 - return ConstantFP::get(CFP1->getType(), - std::numeric_limits<double>::quiet_NaN()); - return ConstantFP::get(CFP1->getType(), std::fmod(C1Val, C2Val)); - + return ConstantFP::get(CFP1->getType(), isDouble ? + APFloat(std::numeric_limits<double>::quiet_NaN()) : + APFloat(std::numeric_limits<float>::quiet_NaN())); + (void)C3V.mod(C2V, APFloat::rmNearestTiesToEven); + return ConstantFP::get(CFP1->getType(), C3V); } } } else if (const ConstantVector *CP1 = dyn_cast<ConstantVector>(C1)) { @@ -1123,52 +1159,47 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, case ICmpInst::ICMP_UGE:return ConstantInt::get(Type::Int1Ty, V1.uge(V2)); } } else if (isa<ConstantFP>(C1) && isa<ConstantFP>(C2)) { - double C1Val = cast<ConstantFP>(C1)->getValue(); - double C2Val = cast<ConstantFP>(C2)->getValue(); + APFloat C1V = cast<ConstantFP>(C1)->getValueAPF(); + APFloat C2V = cast<ConstantFP>(C2)->getValueAPF(); + APFloat::cmpResult R = C1V.compare(C2V); switch (pred) { default: assert(0 && "Invalid FCmp Predicate"); return 0; case FCmpInst::FCMP_FALSE: return ConstantInt::getFalse(); case FCmpInst::FCMP_TRUE: return ConstantInt::getTrue(); case FCmpInst::FCMP_UNO: - return ConstantInt::get(Type::Int1Ty, C1Val != C1Val || C2Val != C2Val); + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered); case FCmpInst::FCMP_ORD: - return ConstantInt::get(Type::Int1Ty, C1Val == C1Val && C2Val == C2Val); + return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpUnordered); case FCmpInst::FCMP_UEQ: - if (C1Val != C1Val || C2Val != C2Val) - return ConstantInt::getTrue(); - /* FALL THROUGH */ + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered || + R==APFloat::cmpEqual); case FCmpInst::FCMP_OEQ: - return ConstantInt::get(Type::Int1Ty, C1Val == C2Val); + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpEqual); case FCmpInst::FCMP_UNE: - if (C1Val != C1Val || C2Val != C2Val) - return ConstantInt::getTrue(); - /* FALL THROUGH */ + return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpEqual); case FCmpInst::FCMP_ONE: - return ConstantInt::get(Type::Int1Ty, C1Val != C2Val); + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpLessThan || + R==APFloat::cmpGreaterThan); case FCmpInst::FCMP_ULT: - if (C1Val != C1Val || C2Val != C2Val) - return ConstantInt::getTrue(); - /* FALL THROUGH */ + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered || + R==APFloat::cmpLessThan); case FCmpInst::FCMP_OLT: - return ConstantInt::get(Type::Int1Ty, C1Val < C2Val); + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpLessThan); case FCmpInst::FCMP_UGT: - if (C1Val != C1Val || C2Val != C2Val) - return ConstantInt::getTrue(); - /* FALL THROUGH */ + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered || + R==APFloat::cmpGreaterThan); case FCmpInst::FCMP_OGT: - return ConstantInt::get(Type::Int1Ty, C1Val > C2Val); + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpGreaterThan); case FCmpInst::FCMP_ULE: - if (C1Val != C1Val || C2Val != C2Val) - return ConstantInt::getTrue(); - /* FALL THROUGH */ + return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpGreaterThan); case FCmpInst::FCMP_OLE: - return ConstantInt::get(Type::Int1Ty, C1Val <= C2Val); + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpLessThan || + R==APFloat::cmpEqual); case FCmpInst::FCMP_UGE: - if (C1Val != C1Val || C2Val != C2Val) - return ConstantInt::getTrue(); - /* FALL THROUGH */ + return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpLessThan); case FCmpInst::FCMP_OGE: - return ConstantInt::get(Type::Int1Ty, C1Val >= C2Val); + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpGreaterThan || + R==APFloat::cmpEqual); } } else if (const ConstantVector *CP1 = dyn_cast<ConstantVector>(C1)) { if (const ConstantVector *CP2 = dyn_cast<ConstantVector>(C2)) { diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index f7cbe82..1708e46 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -107,11 +107,13 @@ Constant *Constant::getNullValue(const Type *Ty) { case Type::IntegerTyID: return ConstantInt::get(Ty, 0); case Type::FloatTyID: + return ConstantFP::get(Ty, APFloat(0.0f)); case Type::DoubleTyID: + return ConstantFP::get(Ty, APFloat(0.0)); case Type::X86_FP80TyID: case Type::PPC_FP128TyID: case Type::FP128TyID: - return ConstantFP::get(Ty, 0.0); + return ConstantFP::get(Ty, APFloat(0.0)); //FIXME case Type::PointerTyID: return ConstantPointerNull::get(cast<PointerType>(Ty)); case Type::StructTyID: @@ -238,11 +240,6 @@ ConstantInt *ConstantInt::get(const APInt& V) { // ConstantFP //===----------------------------------------------------------------------===// - -ConstantFP::ConstantFP(const Type *Ty, double V) - : Constant(Ty, ConstantFPVal, 0, 0), - Val(Ty==Type::FloatTy ? APFloat((float)V) : APFloat(V)) { -} ConstantFP::ConstantFP(const Type *Ty, const APFloat& V) : Constant(Ty, ConstantFPVal, 0, 0), Val(V) { // temporary @@ -293,27 +290,6 @@ typedef DenseMap<DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*, static ManagedStatic<FPMapTy> FPConstants; -ConstantFP *ConstantFP::get(const Type *Ty, double V) { - if (Ty == Type::FloatTy) { - DenseMapAPFloatKeyInfo::KeyTy Key(APFloat((float)V)); - ConstantFP *&Slot = (*FPConstants)[Key]; - if (Slot) return Slot; - return Slot = new ConstantFP(Ty, APFloat((float)V)); - } else if (Ty == Type::DoubleTy) { - // Without the redundant cast, the following is taken to be - // a function declaration. What a language. - DenseMapAPFloatKeyInfo::KeyTy Key(APFloat((double)V)); - ConstantFP *&Slot = (*FPConstants)[Key]; - if (Slot) return Slot; - return Slot = new ConstantFP(Ty, APFloat(V)); - } else if (Ty == Type::X86_FP80Ty || - Ty == Type::PPC_FP128Ty || Ty == Type::FP128Ty) { - assert(0 && "Long double constants not handled yet."); - } else { - assert(0 && "Unknown FP Type!"); - } -} - ConstantFP *ConstantFP::get(const Type *Ty, const APFloat& V) { // temporary if (Ty==Type::FloatTy) @@ -1934,12 +1910,15 @@ Constant *ConstantExpr::getZeroValueForNegationExpr(const Type *Ty) { if (const VectorType *PTy = dyn_cast<VectorType>(Ty)) if (PTy->getElementType()->isFloatingPoint()) { std::vector<Constant*> zeros(PTy->getNumElements(), - ConstantFP::get(PTy->getElementType(),-0.0)); + ConstantFP::get(PTy->getElementType(), + PTy->getElementType()==Type::FloatTy ? + APFloat(-0.0f) : APFloat(0.0))); return ConstantVector::get(PTy, zeros); } if (Ty->isFloatingPoint()) - return ConstantFP::get(Ty, -0.0); + return ConstantFP::get(Ty, Ty==Type::FloatTy ? APFloat(-0.0f) : + APFloat(-0.0)); return Constant::getNullValue(Ty); } |