aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
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) << ')';
@@ -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 8cfd5f9a3c..22b282bd5f 100644
--- a/