Enhance APFloat to retain bits of NaNs (fixes oggenc).

Use APFloat interfaces for more references, mostly
of ConstantFPSDNode.

llvm-svn: 41632
This commit is contained in:
Dale Johannesen 2007-08-31 04:03:46 +00:00
parent ffa8296e3f
commit 81d6ecb886
11 changed files with 155 additions and 113 deletions

View File

@ -64,8 +64,11 @@
so that the smallest denormal has just the least significant bit
of the significand set. The sign of zeroes and infinities is
significant; the exponent and significand of such numbers is
indeterminate and meaningless. For QNaNs the sign bit, as well as
the exponent and significand are indeterminate and meaningless.
not stored, but has a known implicit (deterministic) value:
0 for the significands, 0 for zero exponent, all 1 bits for
infinity exponent. For NaNs the sign and significand are
deterministic, although not really meaningful; the exponent is
implicitly all 1 bits.
TODO
====
@ -155,7 +158,7 @@ namespace llvm {
/* Category of internally-represented number. */
enum fltCategory {
fcInfinity,
fcQNaN,
fcNaN,
fcNormal,
fcZero
};
@ -192,7 +195,7 @@ namespace llvm {
whatever it is you really mean. */
// bool operator==(const APFloat &) const; // DO NOT IMPLEMENT
/* IEEE comparison with another floating point number (QNaNs
/* IEEE comparison with another floating point number (NaNs
compare unordered, 0==-0). */
cmpResult compare(const APFloat &) const;
@ -205,6 +208,8 @@ namespace llvm {
bool isZero() const { return category == fcZero; }
bool isNonZero() const { return category != fcZero; }
bool isNegative() const { return sign; }
bool isPosZero() const { return isZero() && !isNegative(); }
bool isNegZero() const { return isZero() && isNegative(); }
APFloat& operator=(const APFloat &);

View File

@ -15,6 +15,7 @@
#define LLVM_ADT_STRINGEXTRAS_H
#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/APFloat.h"
#include <cctype>
#include <cstdio>
#include <string>
@ -92,6 +93,14 @@ static inline std::string ftostr(double V) {
return B;
}
static inline std::string ftostr(APFloat V) {
if (&V.getSemantics() == &APFloat::IEEEsingle)
return ftostr(V.convertToDouble());
else if (&V.getSemantics() == &APFloat::IEEEdouble)
return ftostr((double)V.convertToFloat());
return 0; // error
}
static inline std::string LowercaseString(const std::string &S) {
std::string result(S);
for (unsigned i = 0; i < S.length(); ++i)

View File

@ -109,11 +109,13 @@ bool ISD::isBuildVectorAllOnes(const SDNode *N) {
} else if (isa<ConstantFPSDNode>(NotZero)) {
MVT::ValueType VT = NotZero.getValueType();
if (VT== MVT::f64) {
if (DoubleToBits(cast<ConstantFPSDNode>(NotZero)->getValue()) !=
if (DoubleToBits(cast<ConstantFPSDNode>(NotZero)->
getValueAPF().convertToDouble()) !=
(uint64_t)-1)
return false;
} else {
if (FloatToBits(cast<ConstantFPSDNode>(NotZero)->getValue()) !=
if (FloatToBits(cast<ConstantFPSDNode>(NotZero)->
getValueAPF().convertToFloat()) !=
(uint32_t)-1)
return false;
}
@ -155,7 +157,7 @@ bool ISD::isBuildVectorAllZeros(const SDNode *N) {
if (!cast<ConstantSDNode>(Zero)->isNullValue())
return false;
} else if (isa<ConstantFPSDNode>(Zero)) {
if (!cast<ConstantFPSDNode>(Zero)->isExactlyValue(0.0))
if (!cast<ConstantFPSDNode>(Zero)->getValueAPF().isPosZero())
return false;
} else
return false;
@ -320,9 +322,16 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, SDNode *N) {
ID.AddInteger(cast<ConstantSDNode>(N)->getValue());
break;
case ISD::TargetConstantFP:
case ISD::ConstantFP:
ID.AddDouble(cast<ConstantFPSDNode>(N)->getValue());
case ISD::ConstantFP: {
APFloat V = cast<ConstantFPSDNode>(N)->getValueAPF();
if (&V.getSemantics() == &APFloat::IEEEdouble)
ID.AddDouble(V.convertToDouble());
else if (&V.getSemantics() == &APFloat::IEEEsingle)
ID.AddDouble((double)V.convertToFloat());
else
assert(0);
break;
}
case ISD::TargetGlobalAddress:
case ISD::GlobalAddress:
case ISD::TargetGlobalTLSAddress:
@ -966,16 +975,36 @@ SDOperand SelectionDAG::FoldSetCC(MVT::ValueType VT, SDOperand N1,
}
if (ConstantFPSDNode *N1C = dyn_cast<ConstantFPSDNode>(N1.Val))
if (ConstantFPSDNode *N2C = dyn_cast<ConstantFPSDNode>(N2.Val)) {
double C1 = N1C->getValue(), C2 = N2C->getValue();
APFloat::cmpResult R = N1C->getValueAPF().compare(N2C->getValueAPF());
switch (Cond) {
default: break; // FIXME: Implement the rest of these!
case ISD::SETEQ: return getConstant(C1 == C2, VT);
case ISD::SETNE: return getConstant(C1 != C2, VT);
case ISD::SETLT: return getConstant(C1 < C2, VT);
case ISD::SETGT: return getConstant(C1 > C2, VT);
case ISD::SETLE: return getConstant(C1 <= C2, VT);
case ISD::SETGE: return getConstant(C1 >= C2, VT);
default: break;
case ISD::SETOEQ:
case ISD::SETEQ: return getConstant(R==APFloat::cmpEqual, VT);
case ISD::SETONE:
case ISD::SETNE: return getConstant(R==APFloat::cmpGreaterThan ||
R==APFloat::cmpLessThan, VT);
case ISD::SETOLT:
case ISD::SETLT: return getConstant(R==APFloat::cmpLessThan, VT);
case ISD::SETOGT:
case ISD::SETGT: return getConstant(R==APFloat::cmpGreaterThan, VT);
case ISD::SETOLE:
case ISD::SETLE: return getConstant(R==APFloat::cmpLessThan ||
R==APFloat::cmpEqual, VT);
case ISD::SETOGE:
case ISD::SETGE: return getConstant(R==APFloat::cmpGreaterThan ||
R==APFloat::cmpEqual, VT);
case ISD::SETO: return getConstant(R!=APFloat::cmpUnordered, VT);
case ISD::SETUO: return getConstant(R==APFloat::cmpUnordered, VT);
case ISD::SETUEQ: return getConstant(R==APFloat::cmpUnordered ||
R==APFloat::cmpEqual, VT);
case ISD::SETUNE: return getConstant(R!=APFloat::cmpEqual, VT);
case ISD::SETULT: return getConstant(R==APFloat::cmpUnordered ||
R==APFloat::cmpLessThan, VT);
case ISD::SETUGT: return getConstant(R==APFloat::cmpGreaterThan ||
R==APFloat::cmpUnordered, VT);
case ISD::SETULE: return getConstant(R!=APFloat::cmpGreaterThan, VT);
case ISD::SETUGE: return getConstant(R!=APFloat::cmpLessThan, VT);
}
} else {
// Ensure that the constant occurs on the RHS.

View File

@ -95,7 +95,7 @@ std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(Node)) {
Op += ": " + utostr(CSDN->getValue());
} else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(Node)) {
Op += ": " + ftostr(CSDN->getValue());
Op += ": " + ftostr(CSDN->getValueAPF());
} else if (const GlobalAddressSDNode *GADN =
dyn_cast<GlobalAddressSDNode>(Node)) {
int offset = GADN->getOffset();
@ -115,7 +115,7 @@ std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
Op += "<" + SS.str() + ">";
} else {
if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
Op += "<" + ftostr(CFP->getValue()) + ">";
Op += "<" + ftostr(CFP->getValueAPF()) + ">";
else if (ConstantInt *CI = dyn_cast<ConstantInt>(CP->getConstVal()))
Op += "<" + utostr(CI->getZExtValue()) + ">";
else {

View File

@ -247,14 +247,14 @@ APFloat::assign(const APFloat &rhs)
sign = rhs.sign;
category = rhs.category;
exponent = rhs.exponent;
if(category == fcNormal)
if(category == fcNormal || category == fcNaN)
copySignificand(rhs);
}
void
APFloat::copySignificand(const APFloat &rhs)
{
assert(category == fcNormal);
assert(category == fcNormal || category == fcNaN);
assert(rhs.partCount() >= partCount());
APInt::tcAssign(significandParts(), rhs.significandParts(),
@ -280,15 +280,14 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
if (this == &rhs)
return true;
if (semantics != rhs.semantics ||
category != rhs.category)
category != rhs.category ||
sign != rhs.sign)
return false;
if (category==fcQNaN)
if (category==fcZero || category==fcInfinity)
return true;
else if (category==fcZero || category==fcInfinity)
return sign==rhs.sign;
else if (category==fcNormal && exponent!=rhs.exponent)
return false;
else {
if (sign!=rhs.sign || exponent!=rhs.exponent)
return false;
int i= partCount();
const integerPart* p=significandParts();
const integerPart* q=rhs.significandParts();
@ -358,7 +357,7 @@ APFloat::significandParts() const
integerPart *
APFloat::significandParts()
{
assert(category == fcNormal);
assert(category == fcNormal || category == fcNaN);
if(partCount() > 1)
return significand.parts;
@ -701,7 +700,7 @@ bool
APFloat::roundAwayFromZero(roundingMode rounding_mode,
lostFraction lost_fraction)
{
/* QNaNs and infinities should not have lost fractions. */
/* NaNs and infinities should not have lost fractions. */
assert(category == fcNormal || category == fcZero);
/* Our caller has already handled this case. */
@ -851,19 +850,20 @@ APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract)
default:
assert(0);
case convolve(fcQNaN, fcZero):
case convolve(fcQNaN, fcNormal):
case convolve(fcQNaN, fcInfinity):
case convolve(fcQNaN, fcQNaN):
case convolve(fcNaN, fcZero):
case convolve(fcNaN, fcNormal):
case convolve(fcNaN, fcInfinity):
case convolve(fcNaN, fcNaN):
case convolve(fcNormal, fcZero):
case convolve(fcInfinity, fcNormal):
case convolve(fcInfinity, fcZero):
return opOK;
case convolve(fcZero, fcQNaN):
case convolve(fcNormal, fcQNaN):
case convolve(fcInfinity, fcQNaN):
category = fcQNaN;
case convolve(fcZero, fcNaN):
case convolve(fcNormal, fcNaN):
case convolve(fcInfinity, fcNaN):
category = fcNaN;
copySignificand(rhs);
return opOK;
case convolve(fcNormal, fcInfinity):
@ -885,7 +885,9 @@ APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract)
/* Differently signed infinities can only be validly
subtracted. */
if(sign ^ rhs.sign != subtract) {
category = fcQNaN;
category = fcNaN;
// Arbitrary but deterministic value for significand
APInt::tcSet(significandParts(), ~0U, partCount());
return opInvalidOp;
}
@ -974,14 +976,17 @@ APFloat::multiplySpecials(const APFloat &rhs)
default:
assert(0);
case convolve(fcQNaN, fcZero):
case convolve(fcQNaN, fcNormal):
case convolve(fcQNaN, fcInfinity):
case convolve(fcQNaN, fcQNaN):
case convolve(fcZero, fcQNaN):
case convolve(fcNormal, fcQNaN):
case convolve(fcInfinity, fcQNaN):
category = fcQNaN;
case convolve(fcNaN, fcZero):
case convolve(fcNaN, fcNormal):
case convolve(fcNaN, fcInfinity):
case convolve(fcNaN, fcNaN):
return opOK;
case convolve(fcZero, fcNaN):
case convolve(fcNormal, fcNaN):
case convolve(fcInfinity, fcNaN):
category = fcNaN;
copySignificand(rhs);
return opOK;
case convolve(fcNormal, fcInfinity):
@ -998,7 +1003,9 @@ APFloat::multiplySpecials(const APFloat &rhs)
case convolve(fcZero, fcInfinity):
case convolve(fcInfinity, fcZero):
category = fcQNaN;
category = fcNaN;
// Arbitrary but deterministic value for significand
APInt::tcSet(significandParts(), ~0U, partCount());
return opInvalidOp;
case convolve(fcNormal, fcNormal):
@ -1013,20 +1020,21 @@ APFloat::divideSpecials(const APFloat &rhs)
default:
assert(0);
case convolve(fcQNaN, fcZero):
case convolve(fcQNaN, fcNormal):
case convolve(fcQNaN, fcInfinity):
case convolve(fcQNaN, fcQNaN):
case convolve(fcNaN, fcZero):
case convolve(fcNaN, fcNormal):
case convolve(fcNaN, fcInfinity):
case convolve(fcNaN, fcNaN):
case convolve(fcInfinity, fcZero):
case convolve(fcInfinity, fcNormal):
case convolve(fcZero, fcInfinity):
case convolve(fcZero, fcNormal):
return opOK;
case convolve(fcZero, fcQNaN):
case convolve(fcNormal, fcQNaN):
case convolve(fcInfinity, fcQNaN):
category = fcQNaN;
case convolve(fcZero, fcNaN):
case convolve(fcNormal, fcNaN):
case convolve(fcInfinity, fcNaN):
category = fcNaN;
copySignificand(rhs);
return opOK;
case convolve(fcNormal, fcInfinity):
@ -1039,7 +1047,9 @@ APFloat::divideSpecials(const APFloat &rhs)
case convolve(fcInfinity, fcInfinity):
case convolve(fcZero, fcZero):
category = fcQNaN;
category = fcNaN;
// Arbitrary but deterministic value for significand
APInt::tcSet(significandParts(), ~0U, partCount());
return opInvalidOp;
case convolve(fcNormal, fcNormal):
@ -1172,7 +1182,7 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
/* FS can only be opOK or opInvalidOp. There is no more work
to do in the latter case. The IEEE-754R standard says it is
implementation-defined in this case whether, if ADDEND is a
quiet QNaN, we raise invalid op; this implementation does so.
quiet NaN, we raise invalid op; this implementation does so.
If we need to do the addition we can do so with normal
precision. */
@ -1195,13 +1205,13 @@ APFloat::compare(const APFloat &rhs) const
default:
assert(0);
case convolve(fcQNaN, fcZero):
case convolve(fcQNaN, fcNormal):
case convolve(fcQNaN, fcInfinity):
case convolve(fcQNaN, fcQNaN):
case convolve(fcZero, fcQNaN):
case convolve(fcNormal, fcQNaN):
case convolve(fcInfinity, fcQNaN):
case convolve(fcNaN, fcZero):
case convolve(fcNaN, fcNormal):
case convolve(fcNaN, fcInfinity):
case convolve(fcNaN, fcNaN):
case convolve(fcZero, fcNaN):
case convolve(fcNormal, fcNaN):
case convolve(fcInfinity, fcNaN):
return cmpUnordered;
case convolve(fcInfinity, fcNormal):
@ -1309,7 +1319,7 @@ APFloat::convertToInteger(integerPart *parts, unsigned int width,
int bits;
/* Handle the three special cases first. */
if(category == fcInfinity || category == fcQNaN)
if(category == fcInfinity || category == fcNaN)
return opInvalidOp;
partsCount = partCountForBits(width);
@ -1517,7 +1527,7 @@ uint32_t
APFloat::getHashValue() const {
if (category==fcZero) return sign<<8 | semantics->precision ;
else if (category==fcInfinity) return sign<<9 | semantics->precision;
else if (category==fcQNaN) return 1<<10 | semantics->precision;
else if (category==fcNaN) return 1<<10 | semantics->precision;
else {
uint32_t hash = sign<<11 | semantics->precision | exponent<<12;
const integerPart* p = significandParts();
@ -1538,28 +1548,25 @@ APFloat::convertToDouble() const {
assert(semantics == (const llvm::fltSemantics* const)&IEEEdouble);
assert (partCount()==1);
uint64_t myexponent, mysign, mysignificand;
uint64_t myexponent, mysignificand;
if (category==fcNormal) {
mysign = sign;
mysignificand = *significandParts();
myexponent = exponent+1023; //bias
} else if (category==fcZero) {
mysign = sign;
myexponent = 0;
mysignificand = 0;
} else if (category==fcInfinity) {
mysign = sign;
myexponent = 0x7ff;
mysignificand = 0;
} else if (category==fcQNaN) {
mysign = 0;
} else if (category==fcNaN) {
myexponent = 0x7ff;
mysignificand = 0xfffffffffffffLL;
mysignificand = *significandParts();
} else
assert(0);
return BitsToDouble(((mysign & 1) << 63) | ((myexponent & 0x7ff) << 52) |
return BitsToDouble((((uint64_t)sign & 1) << 63) |
((myexponent & 0x7ff) << 52) |
(mysignificand & 0xfffffffffffffLL));
}
@ -1568,82 +1575,74 @@ APFloat::convertToFloat() const {
assert(semantics == (const llvm::fltSemantics* const)&IEEEsingle);
assert (partCount()==1);
uint32_t mysign, myexponent, mysignificand;
uint32_t myexponent, mysignificand;
if (category==fcNormal) {
mysign = sign;
myexponent = exponent+127; //bias
mysignificand = *significandParts();
} else if (category==fcZero) {
mysign = sign;
myexponent = 0;
mysignificand = 0;
} else if (category==fcInfinity) {
mysign = sign;
myexponent = 0xff;
mysignificand = 0;
} else if (category==fcQNaN) {
mysign = sign;
} else if (category==fcNaN) {
myexponent = 0x7ff;
mysignificand = 0x7fffff;
mysignificand = *significandParts();
} else
assert(0);
return BitsToFloat(((mysign&1) << 31) | ((myexponent&0xff) << 23) |
return BitsToFloat(((sign&1) << 31) | ((myexponent&0xff) << 23) |
(mysignificand & 0x7fffff));
}
APFloat::APFloat(double d) {
uint64_t i = DoubleToBits(d);
uint64_t mysign = i >> 63;
uint64_t myexponent = (i >> 52) & 0x7ff;
uint64_t mysignificand = i & 0xfffffffffffffLL;
initialize(&APFloat::IEEEdouble);
assert(partCount()==1);
sign = i>>63;
if (myexponent==0 && mysignificand==0) {
// exponent, significand meaningless
category = fcZero;
sign = mysign;
} else if (myexponent==0x7ff && mysignificand==0) {
// exponent, significand meaningless
category = fcInfinity;
sign = mysign;
} else if (myexponent==0x7ff && (mysignificand & 0x8000000000000LL)) {
// sign, exponent, significand meaningless
category = fcQNaN;
} else if (myexponent==0x7ff && mysignificand!=0) {
// exponent meaningless
category = fcNaN;
*significandParts() = mysignificand;
} else {
sign = mysign;
category = fcNormal;
exponent = myexponent - 1023;
*significandParts() = mysignificand | 0x10000000000000LL;
}
*significandParts() = mysignificand | 0x10000000000000LL;
}
}
APFloat::APFloat(float f) {
uint32_t i = FloatToBits(f);
uint32_t mysign = i >> 31;
uint32_t myexponent = (i >> 23) & 0xff;
uint32_t mysignificand = i & 0x7fffff;
initialize(&APFloat::IEEEsingle);
assert(partCount()==1);
sign = i >> 31;
if (myexponent==0 && mysignificand==0) {
// exponent, significand meaningless
category = fcZero;
sign = mysign;
} else if (myexponent==0xff && mysignificand==0) {
// exponent, significand meaningless
category = fcInfinity;
sign = mysign;
} else if (myexponent==0xff && (mysignificand & 0x400000)) {
// sign, exponent, significand meaningless
category = fcQNaN;
category = fcNaN;
*significandParts() = mysignificand;
} else {
category = fcNormal;
sign = mysign;
exponent = myexponent - 127; //bias
*significandParts() = mysignificand | 0x800000; // integer bit
}

View File

@ -1033,14 +1033,14 @@ ARMTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
/// isFloatingPointZero - Return true if this is +0.0.
static bool isFloatingPointZero(SDOperand Op) {
if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op))
return CFP->isExactlyValue(0.0);
return CFP->getValueAPF().isPosZero();
else if (ISD::isEXTLoad(Op.Val) || ISD::isNON_EXTLoad(Op.Val)) {
// Maybe this has already been legalized into the constant pool?
if (Op.getOperand(1).getOpcode() == ARMISD::Wrapper) {
SDOperand WrapperOp = Op.getOperand(1).getOperand(0);
if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(WrapperOp))
if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
return CFP->isExactlyValue(0.0);
return CFP->getValueAPF().isPosZero();
}
}
return false;

View File

@ -131,15 +131,15 @@ namespace {
static bool isFPZ(SDOperand N) {
ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
return (CN && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)));
return (CN && (CN->getValueAPF().isZero()));
}
static bool isFPZn(SDOperand N) {
ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
return (CN && CN->isExactlyValue(-0.0));
return (CN && CN->getValueAPF().isNegZero());
}
static bool isFPZp(SDOperand N) {
ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
return (CN && CN->isExactlyValue(+0.0));
return (CN && CN->getValueAPF().isPosZero());
}
public:
@ -334,11 +334,11 @@ SDNode *AlphaDAGToDAGISel::Select(SDOperand Op) {
ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N);
bool isDouble = N->getValueType(0) == MVT::f64;
MVT::ValueType T = isDouble ? MVT::f64 : MVT::f32;
if (CN->isExactlyValue(+0.0)) {
if (CN->getValueAPF().isPosZero()) {
return CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYST : Alpha::CPYSS,
T, CurDAG->getRegister(Alpha::F31, T),
CurDAG->getRegister(Alpha::F31, T));
} else if ( CN->isExactlyValue(-0.0)) {
} else if (CN->getValueAPF().isNegZero()) {
return CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYSNT : Alpha::CPYSNS,
T, CurDAG->getRegister(Alpha::F31, T),
CurDAG->getRegister(Alpha::F31, T));

View File

@ -404,9 +404,9 @@ SDNode *IA64DAGToDAGISel::Select(SDOperand Op) {
SDOperand Chain = CurDAG->getEntryNode(); // this is a constant, so..
SDOperand V;
if (cast<ConstantFPSDNode>(N)->isExactlyValue(+0.0)) {
if (cast<ConstantFPSDNode>(N)->getValueAPF().isPosZero()) {
V = CurDAG->getCopyFromReg(Chain, IA64::F0, MVT::f64);
} else if (cast<ConstantFPSDNode>(N)->isExactlyValue(+1.0)) {
} else if (cast<ConstantFPSDNode>(N)->isExactlyValue(APFloat(+1.0))) {
V = CurDAG->getCopyFromReg(Chain, IA64::F1, MVT::f64);
} else
assert(0 && "Unexpected FP constant!");

View File

@ -362,12 +362,12 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
/// isFloatingPointZero - Return true if this is 0.0 or -0.0.
static bool isFloatingPointZero(SDOperand Op) {
if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op))
return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0);
return CFP->getValueAPF().isZero();
else if (ISD::isEXTLoad(Op.Val) || ISD::isNON_EXTLoad(Op.Val)) {
// Maybe this has already been legalized into the constant pool?
if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op.getOperand(1)))
if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0);
return CFP->getValueAPF().isZero();
}
return false;
}
@ -530,7 +530,7 @@ bool PPC::isAllNegativeZeroVector(SDNode *N) {
assert(N->getOpcode() == ISD::BUILD_VECTOR);
if (PPC::isSplatShuffleMask(N, N->getNumOperands()))
if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N))
return CFP->isExactlyValue(-0.0);
return CFP->getValueAPF().isNegZero();
return false;
}
@ -622,7 +622,7 @@ SDOperand PPC::get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) {
ValSizeInBytes = MVT::getSizeInBits(CN->getValueType(0))/8;
} else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
assert(CN->getValueType(0) == MVT::f32 && "Only one legal FP vector type!");
Value = FloatToBits(CN->getValue());
Value = FloatToBits(CN->getValueAPF().convertToFloat());
ValSizeInBytes = 4;
}
@ -2194,7 +2194,7 @@ static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
} else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
EltBits = FloatToBits(CN->getValue());
EltBits = FloatToBits(CN->getValueAPF().convertToFloat());
} else {
// Nonconstant element.
return true;

View File

@ -817,7 +817,7 @@ static inline bool isZeroNode(SDOperand Elt) {
return ((isa<ConstantSDNode>(Elt) &&
cast<ConstantSDNode>(Elt)->getValue() == 0) ||
(isa<ConstantFPSDNode>(Elt) &&
cast<ConstantFPSDNode>(Elt)->isExactlyValue(0.0)));
cast<ConstantFPSDNode>(Elt)->getValueAPF().isPosZero()));
}

View File

@ -2303,7 +2303,7 @@ static inline bool isZeroNode(SDOperand Elt) {
return ((isa<ConstantSDNode>(Elt) &&
cast<ConstantSDNode>(Elt)->getValue() == 0) ||
(isa<ConstantFPSDNode>(Elt) &&
cast<ConstantFPSDNode>(Elt)->isExactlyValue(0.0)));
cast<ConstantFPSDNode>(Elt)->getValueAPF().isPosZero()));
}
/// isZeroShuffle - Returns true if N is a VECTOR_SHUFFLE that can be resolved