aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2007-09-06 18:13:44 +0000
committerDale Johannesen <dalej@apple.com>2007-09-06 18:13:44 +0000
commit43421b3dd70af5b70e71816521f37502c397cc65 (patch)
treeb314e17b0444f33dc3be37eaeaeaa8ea7dd1d17e /lib
parent325be7c608a37d87e4f3d731e11fa3dd34f529b5 (diff)
Next round of APFloat changes.
Use APFloat in UpgradeParser and AsmParser. Change all references to ConstantFP to use the APFloat interface rather than double. Remove the ConstantFP double interfaces. Use APFloat functions for constant folding arithmetic and comparisons. (There are still way too many places APFloat is just a wrapper around host float/double, but we're getting there.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41747 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/ConstantFolding.cpp55
-rw-r--r--lib/Analysis/ScalarEvolution.cpp3
-rw-r--r--lib/AsmParser/Lexer.cpp.cvs18
-rw-r--r--lib/AsmParser/Lexer.l6
-rw-r--r--lib/AsmParser/Lexer.l.cvs6
-rw-r--r--lib/AsmParser/ParserInternals.h16
-rw-r--r--lib/AsmParser/llvmAsmParser.h.cvs2
-rw-r--r--lib/AsmParser/llvmAsmParser.y18
-rw-r--r--lib/AsmParser/llvmAsmParser.y.cvs18
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp15
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp5
-rw-r--r--lib/CodeGen/AsmPrinter.cpp3
-rw-r--r--lib/CodeGen/MachOWriter.cpp6
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp5
-rw-r--r--lib/ExecutionEngine/ExecutionEngine.cpp4
-rw-r--r--lib/ExecutionEngine/JIT/JIT.cpp6
-rw-r--r--lib/Target/CBackend/CBackend.cpp34
-rw-r--r--lib/Target/MSIL/MSILWriter.cpp10
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp33
-rw-r--r--lib/Transforms/IPO/SimplifyLibCalls.cpp27
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp2
-rw-r--r--lib/VMCore/AsmWriter.cpp9
-rw-r--r--lib/VMCore/ConstantFold.cpp163
-rw-r--r--lib/VMCore/Constants.cpp37
24 files changed, 295 insertions, 206 deletions
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];
- 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 5859adf87a..71789703ff 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) <<