forked from OSchip/llvm-project
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.) llvm-svn: 41747
This commit is contained in:
parent
a07765b8f4
commit
bed9dc423c
|
@ -217,29 +217,13 @@ class ConstantFP : public Constant {
|
|||
APFloat Val;
|
||||
ConstantFP(const ConstantFP &); // DO NOT IMPLEMENT
|
||||
protected:
|
||||
ConstantFP(const Type *Ty, double V);
|
||||
ConstantFP(const Type *Ty, const APFloat& V);
|
||||
public:
|
||||
/// get() - Static factory methods - Return objects of the specified value
|
||||
static ConstantFP *get(const Type *Ty, double V);
|
||||
static ConstantFP *get(const Type *Ty, const APFloat& V);
|
||||
|
||||
/// isValueValidForType - return true if Ty is big enough to represent V.
|
||||
static bool isValueValidForType(const Type *Ty, const APFloat& V);
|
||||
static bool isValueValidForType(const Type *Ty, double V) {
|
||||
if (Ty == Type::FloatTy)
|
||||
return isValueValidForType(Ty, APFloat((float)V));
|
||||
else
|
||||
return isValueValidForType(Ty, APFloat(V));
|
||||
}
|
||||
inline double getValue() const {
|
||||
if (&Val.getSemantics() == &APFloat::IEEEdouble)
|
||||
return Val.convertToDouble();
|
||||
else if (&Val.getSemantics() == &APFloat::IEEEsingle)
|
||||
return (double)Val.convertToFloat();
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
inline const APFloat& getValueAPF() const { return Val; }
|
||||
|
||||
/// isNullValue - Return true if this is the value that would be returned by
|
||||
|
@ -250,8 +234,11 @@ public:
|
|||
/// isExactlyValue - We don't rely on operator== working on double values, as
|
||||
/// it returns true for things that are clearly not equal, like -0.0 and 0.0.
|
||||
/// As such, this method can be used to do an exact bit-for-bit comparison of
|
||||
/// two floating point values.
|
||||
/// two floating point values. The version with a double operand is retained
|
||||
/// because it's so convenient to write isExactlyValue(2.0), but please use
|
||||
/// it only for constants.
|
||||
bool isExactlyValue(const APFloat& V) const;
|
||||
|
||||
bool isExactlyValue(double V) const {
|
||||
if (&Val.getSemantics() == &APFloat::IEEEdouble)
|
||||
return isExactlyValue(APFloat(V));
|
||||
|
|
|
@ -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())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,7 +93,7 @@ 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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,10 +921,10 @@ 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;
|
||||
}
|
||||
|
@ -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";
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
(void)C3V.add(C2V, APFloat::rmNearestTiesToEven);
|
||||
return ConstantFP::get(CFP1->getType(), C3V);
|
||||
case Instruction::Sub:
|
||||
return ConstantFP::get(CFP1->getType(), C1Val - C2Val);
|
||||
(void)C3V.subtract(C2V, APFloat::rmNearestTiesToEven);
|
||||
return ConstantFP::get(CFP1->getType(), C3V);
|
||||
case Instruction::Mul:
|
||||
return ConstantFP::get(CFP1->getType(), C1Val * C2Val);
|
||||
(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)) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -159,7 +159,7 @@ struct ValID {
|
|||
char *Name; // If it's a named reference. Memory must be free'd.
|
||||
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;
|
||||
};
|
||||
|
@ -187,7 +187,7 @@ struct ValID {
|
|||
return D;
|
||||
}
|
||||
|
||||
static ValID create(double Val) {
|
||||
static ValID create(APFloat* Val) {
|
||||
ValID D; D.Type = ConstFPVal; D.ConstPoolFP = Val;
|
||||
D.S.makeSignless();
|
||||
return D;
|
||||
|
@ -245,7 +245,7 @@ struct ValID {
|
|||
switch (Type) {
|
||||
case NumberVal : return std::string("#") + itostr(Num);
|
||||
case NameVal : return Name;
|
||||
case ConstFPVal : return ftostr(ConstPoolFP);
|
||||
case ConstFPVal : return ftostr(*ConstPoolFP);
|
||||
case ConstNullVal : return "null";
|
||||
case ConstUndefVal : return "undef";
|
||||
case ConstZeroVal : return "zeroinitializer";
|
||||
|
@ -271,7 +271,8 @@ struct ValID {
|
|||
case NameVal: return strcmp(Name, V.Name) < 0;
|
||||
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;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -410,8 +410,10 @@ shufflevector { RET_TOK(OtherOpVal, ShuffleVectorOp, SHUFFLEVECTOR); }
|
|||
return SINTVAL;
|
||||
}
|
||||
|
||||
{FPConstant} { Upgradelval.FPVal = atof(yytext); return FPVAL; }
|
||||
{HexFPConstant} { Upgradelval.FPVal = HexToFP(yytext); return FPVAL; }
|
||||
{FPConstant} { Upgradelval.FPVal = new APFloat(atof(yytext)); return FPVAL; }
|
||||
{HexFPConstant} { Upgradelval.FPVal = new APFloat(HexToFP(yytext));
|
||||
return FPVAL;
|
||||
}
|
||||
|
||||
<<EOF>> {
|
||||
/* Make sure to free the internal buffers for flex when we are
|
||||
|
|
|
@ -410,8 +410,10 @@ shufflevector { RET_TOK(OtherOpVal, ShuffleVectorOp, SHUFFLEVECTOR); }
|
|||
return SINTVAL;
|
||||
}
|
||||
|
||||
{FPConstant} { Upgradelval.FPVal = atof(yytext); return FPVAL; }
|
||||
{HexFPConstant} { Upgradelval.FPVal = HexToFP(yytext); return FPVAL; }
|
||||
{FPConstant} { Upgradelval.FPVal = new APFloat(atof(yytext)); return FPVAL; }
|
||||
{HexFPConstant} { Upgradelval.FPVal = new APFloat(HexToFP(yytext));
|
||||
return FPVAL;
|
||||
}
|
||||
|
||||
<<EOF>> {
|
||||
/* Make sure to free the internal buffers for flex when we are
|
||||
|
|
|
@ -533,9 +533,13 @@ static Value *getExistingValue(const Type *Ty, const ValID &D) {
|
|||
return ConstantInt::get(Ty, D.UConstPool64);
|
||||
|
||||
case ValID::ConstFPVal: // Is it a floating point const pool reference?
|
||||
if (!ConstantFP::isValueValidForType(Ty, D.ConstPoolFP))
|
||||
if (!ConstantFP::isValueValidForType(Ty, *D.ConstPoolFP))
|
||||
error("FP constant invalid for type");
|
||||
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))
|
||||
|
@ -1773,7 +1777,7 @@ using namespace llvm;
|
|||
uint64_t UInt64Val;
|
||||
int SIntVal;
|
||||
unsigned UIntVal;
|
||||
double FPVal;
|
||||
llvm::APFloat *FPVal;
|
||||
bool BoolVal;
|
||||
|
||||
char *StrVal; // This memory is strdup'd!
|
||||
|
@ -2514,9 +2518,13 @@ ConstVal
|
|||
$$.S.makeUnsigned();
|
||||
}
|
||||
| FPType FPVAL { // Float & Double constants
|
||||
if (!ConstantFP::isValueValidForType($1.T, $2))
|
||||
if (!ConstantFP::isValueValidForType($1.T, *$2))
|
||||
error("Floating point constant invalid for type");
|
||||
$$.C = ConstantFP::get($1.T, $2);
|
||||
// Lexer has no type info, so builds all FP constants as double.
|
||||
// Fix this here.
|
||||
if ($1.T==Type::FloatTy)
|
||||
$2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven);
|
||||
$$.C = ConstantFP::get($1.T, *$2);
|
||||
$$.S.makeSignless();
|
||||
}
|
||||
;
|
||||
|
|
|
@ -533,9 +533,13 @@ static Value *getExistingValue(const Type *Ty, const ValID &D) {
|
|||
return ConstantInt::get(Ty, D.UConstPool64);
|
||||
|
||||
case ValID::ConstFPVal: // Is it a floating point const pool reference?
|
||||
if (!ConstantFP::isValueValidForType(Ty, D.ConstPoolFP))
|
||||
if (!ConstantFP::isValueValidForType(Ty, *D.ConstPoolFP))
|
||||
error("FP constant invalid for type");
|
||||
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))
|
||||
|
@ -1773,7 +1777,7 @@ using namespace llvm;
|
|||
uint64_t UInt64Val;
|
||||
int SIntVal;
|
||||
unsigned UIntVal;
|
||||
double FPVal;
|
||||
llvm::APFloat *FPVal;
|
||||
bool BoolVal;
|
||||
|
||||
char *StrVal; // This memory is strdup'd!
|
||||
|
@ -2514,9 +2518,13 @@ ConstVal
|
|||
$$.S.makeUnsigned();
|
||||
}
|
||||
| FPType FPVAL { // Float & Double constants
|
||||
if (!ConstantFP::isValueValidForType($1.T, $2))
|
||||
if (!ConstantFP::isValueValidForType($1.T, *$2))
|
||||
error("Floating point constant invalid for type");
|
||||
$$.C = ConstantFP::get($1.T, $2);
|
||||
// Lexer has no type info, so builds all FP constants as double.
|
||||
// Fix this here.
|
||||
if ($1.T==Type::FloatTy)
|
||||
$2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven);
|
||||
$$.C = ConstantFP::get($1.T, *$2);
|
||||
$$.S.makeSignless();
|
||||
}
|
||||
;
|
||||
|
|
|
@ -209,25 +209,30 @@ CppWriter::error(const std::string& msg) {
|
|||
// result so that we don't lose precision.
|
||||
void
|
||||
CppWriter::printCFP(const ConstantFP *CFP) {
|
||||
APFloat APF = APFloat(CFP->getValueAPF()); // copy
|
||||
if (CFP->getType() == Type::FloatTy)
|
||||
APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven);
|
||||
Out << "ConstantFP::get(";
|
||||
if (CFP->getType() == Type::DoubleTy)
|
||||
Out << "Type::DoubleTy, ";
|
||||
else
|
||||
Out << "Type::FloatTy, ";
|
||||
Out << "APFloat(";
|
||||
#if HAVE_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)) &&
|
||||
(atof(Buffer) == CFP->getValue()))
|
||||
APF.bitwiseIsEqual(APFloat(atof(Buffer)))) {
|
||||
if (CFP->getType() == Type::DoubleTy)
|
||||
Out << "BitsToDouble(" << Buffer << ")";
|
||||
else
|
||||
Out << "BitsToFloat(" << Buffer << ")";
|
||||
else {
|
||||
Out << "BitsToFloat((float)" << Buffer << ")";
|
||||
Out << ")";
|
||||
} else {
|
||||
#endif
|
||||
std::string StrVal = ftostr(CFP->getValue());
|
||||
std::string StrVal = ftostr(CFP->getValueAPF());
|
||||
|
||||
while (StrVal[0] == ' ')
|
||||
StrVal.erase(StrVal.begin());
|
||||
|
@ -237,17 +242,21 @@ CppWriter::printCFP(const ConstantFP *CFP) {
|
|||
if (((StrVal[0] >= '0' && StrVal[0] <= '9') ||
|
||||
((StrVal[0] == '-' || StrVal[0] == '+') &&
|
||||
(StrVal[1] >= '0' && StrVal[1] <= '9'))) &&
|
||||
(atof(StrVal.c_str()) == CFP->getValue()))
|
||||
(CFP->isExactlyValue(atof(StrVal.c_str())))) {
|
||||
if (CFP->getType() == Type::DoubleTy)
|
||||
Out << StrVal;
|
||||
else
|
||||
Out << StrVal;
|
||||
Out << StrVal << "f";
|
||||
}
|
||||
else if (CFP->getType() == Type::DoubleTy)
|
||||
Out << "BitsToDouble(0x" << std::hex << DoubleToBits(CFP->getValue())
|
||||
Out << "BitsToDouble(0x" << std::hex
|
||||
<< DoubleToBits(CFP->getValueAPF().convertToDouble())
|
||||
<< std::dec << "ULL) /* " << StrVal << " */";
|
||||
else
|
||||
Out << "BitsToFloat(0x" << std::hex << FloatToBits(CFP->getValue())
|
||||
Out << "BitsToFloat(0x" << std::hex
|
||||
<< FloatToBits(CFP->getValueAPF().convertToFloat())
|
||||
<< std::dec << "U) /* " << StrVal << " */";
|
||||
Out << ")";
|
||||
#if HAVE_PRINTF_A
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue