aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2007-08-30 00:23:21 +0000
committerDale Johannesen <dalej@apple.com>2007-08-30 00:23:21 +0000
commitf04afdbb48568ef09f11fd10ac03426101f2dbf8 (patch)
treedf18d3207060fa0327a208f95cf643e386a3de7d /lib
parent055c5449a4046a5e1a5210d2f91aee4e3901cccf (diff)
Change LegalFPImmediates to use APFloat.
Add APFloat interfaces to ConstantFP, SelectionDAG. Fix integer bit in double->APFloat conversion. Convert LegalizeDAG to use APFloat interface in ConstantFPSDNode uses. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41587 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp21
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp44
-rw-r--r--lib/Support/APFloat.cpp2
-rw-r--r--lib/Target/Alpha/AlphaISelLowering.cpp4
-rw-r--r--lib/Target/IA64/IA64ISelLowering.cpp4
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp10
-rw-r--r--lib/VMCore/Constants.cpp45
7 files changed, 101 insertions, 29 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index c7803caa83..265209c682 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -487,15 +487,15 @@ static SDOperand ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP,
MVT::ValueType VT = CFP->getValueType(0);
bool isDouble = VT == MVT::f64;
ConstantFP *LLVMC = ConstantFP::get(isDouble ? Type::DoubleTy :
- Type::FloatTy, CFP->getValue());
+ Type::FloatTy, CFP->getValueAPF());
if (!UseCP) {
- double Val = LLVMC->getValue();
+ const APFloat& Val = LLVMC->getValueAPF();
return isDouble
- ? DAG.getConstant(DoubleToBits(Val), MVT::i64)
- : DAG.getConstant(FloatToBits(Val), MVT::i32);
+ ? DAG.getConstant(DoubleToBits(Val.convertToDouble()), MVT::i64)
+ : DAG.getConstant(FloatToBits(Val.convertToFloat()), MVT::i32);
}
- if (isDouble && CFP->isExactlyValue((float)CFP->getValue()) &&
+ if (isDouble && CFP->isValueValidForType(MVT::f32, CFP->getValueAPF()) &&
// Only do this if the target has a native EXTLOAD instruction from f32.
TLI.isLoadXLegal(ISD::EXTLOAD, MVT::f32)) {
LLVMC = cast<ConstantFP>(ConstantExpr::getFPTrunc(LLVMC,Type::FloatTy));
@@ -1017,7 +1017,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
// If this is a legal constant, turn it into a TargetConstantFP node.
if (isLegal) {
- Result = DAG.getTargetConstantFP(CFP->getValue(), CFP->getValueType(0));
+ Result = DAG.getTargetConstantFP(CFP->getValueAPF(),
+ CFP->getValueType(0));
break;
}
@@ -1942,10 +1943,12 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
// together.
if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(ST->getValue())) {
if (CFP->getValueType(0) == MVT::f32) {
- Tmp3 = DAG.getConstant(FloatToBits(CFP->getValue()), MVT::i32);
+ Tmp3 = DAG.getConstant(FloatToBits(CFP->getValueAPF().
+ convertToFloat()), MVT::i32);
} else {
assert(CFP->getValueType(0) == MVT::f64 && "Unknown FP type!");
- Tmp3 = DAG.getConstant(DoubleToBits(CFP->getValue()), MVT::i64);
+ Tmp3 = DAG.getConstant(DoubleToBits(CFP->getValueAPF().
+ convertToDouble()), MVT::i64);
}
Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
SVOffset, isVolatile, Alignment);
@@ -4212,7 +4215,7 @@ SDOperand SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
for (unsigned i = 0, e = NumElems; i != e; ++i) {
if (ConstantFPSDNode *V =
dyn_cast<ConstantFPSDNode>(Node->getOperand(i))) {
- CV.push_back(ConstantFP::get(OpNTy, V->getValue()));
+ CV.push_back(ConstantFP::get(OpNTy, V->getValueAPF()));
} else if (ConstantSDNode *V =
dyn_cast<ConstantSDNode>(Node->getOperand(i))) {
CV.push_back(ConstantInt::get(OpNTy, V->getValue()));
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 055834b503..d544e8e37c 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -52,6 +52,32 @@ bool ConstantFPSDNode::isExactlyValue(const APFloat& V) const {
return Value.bitwiseIsEqual(V);
}
+bool ConstantFPSDNode::isValueValidForType(MVT::ValueType VT,
+ const APFloat& Val) {
+ // convert modifies in place, so make a copy.
+ APFloat Val2 = APFloat(Val);
+ switch (VT) {
+ default:
+ return false; // These can't be represented as floating point!
+
+ // FIXME rounding mode needs to be more flexible
+ case MVT::f32:
+ return &Val2.getSemantics() == &APFloat::IEEEsingle ||
+ Val2.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven) ==
+ APFloat::opOK;
+ case MVT::f64:
+ return &Val2.getSemantics() == &APFloat::IEEEsingle ||
+ &Val2.getSemantics() == &APFloat::IEEEdouble ||
+ Val2.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven) ==
+ APFloat::opOK;
+ // TODO: Figure out how to test if we can use a shorter type instead!
+ case MVT::f80:
+ case MVT::f128:
+ case MVT::ppcf128:
+ return true;
+ }
+}
+
//===----------------------------------------------------------------------===//
// ISD Namespace
//===----------------------------------------------------------------------===//
@@ -669,18 +695,20 @@ SDOperand SelectionDAG::getConstant(uint64_t Val, MVT::ValueType VT, bool isT) {
return SDOperand(N, 0);
}
-SDOperand SelectionDAG::getConstantFP(double Val, MVT::ValueType VT,
+SDOperand SelectionDAG::getConstantFP(const APFloat& V, MVT::ValueType VT,
bool isTarget) {
assert(MVT::isFloatingPoint(VT) && "Cannot create integer FP constant!");
+
MVT::ValueType EltVT =
MVT::isVector(VT) ? MVT::getVectorElementType(VT) : VT;
- if (EltVT == MVT::f32)
- Val = (float)Val; // Mask out extra precision.
+ bool isDouble = (EltVT == MVT::f64);
+ double Val = isDouble ? V.convertToDouble() : (double)V.convertToFloat();
// Do the map lookup using the actual bit pattern for the floating point
// value, so that we don't have problems with 0.0 comparing equal to -0.0, and
// we don't have issues with SNANs.
unsigned Opc = isTarget ? ISD::TargetConstantFP : ISD::ConstantFP;
+ // ?? Should we store float/double/longdouble separately in ID?
FoldingSetNodeID ID;
AddNodeIDNode(ID, Opc, getVTList(EltVT), 0, 0);
ID.AddDouble(Val);
@@ -704,6 +732,16 @@ SDOperand SelectionDAG::getConstantFP(double Val, MVT::ValueType VT,
return Result;
}
+SDOperand SelectionDAG::getConstantFP(double Val, MVT::ValueType VT,
+ bool isTarget) {
+ MVT::ValueType EltVT =
+ MVT::isVector(VT) ? MVT::getVectorElementType(VT) : VT;
+ if (EltVT==MVT::f32)
+ return getConstantFP(APFloat((float)Val), VT, isTarget);
+ else
+ return getConstantFP(APFloat(Val), VT, isTarget);
+}
+
SDOperand SelectionDAG::getGlobalAddress(const GlobalValue *GV,
MVT::ValueType VT, int Offset,
bool isTargetGA) {
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index d2e52adb17..47ec9eeaea 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -1617,7 +1617,7 @@ APFloat::APFloat(double d) {
sign = mysign;
category = fcNormal;
exponent = myexponent - 1023;
- *significandParts() = mysignificand | 0x100000000000000LL;
+ *significandParts() = mysignificand | 0x10000000000000LL;
}
}
diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp
index adbf322dad..faeb791824 100644
--- a/lib/Target/Alpha/AlphaISelLowering.cpp
+++ b/lib/Target/Alpha/AlphaISelLowering.cpp
@@ -142,8 +142,8 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
- addLegalFPImmediate(+0.0); //F31
- addLegalFPImmediate(-0.0); //-F31
+ addLegalFPImmediate(APFloat(+0.0)); //F31
+ addLegalFPImmediate(APFloat(-0.0)); //-F31
setJumpBufSize(272);
setJumpBufAlignment(16);
diff --git a/lib/Target/IA64/IA64ISelLowering.cpp b/lib/Target/IA64/IA64ISelLowering.cpp
index b9508a9cb3..8f62c1f419 100644
--- a/lib/Target/IA64/IA64ISelLowering.cpp
+++ b/lib/Target/IA64/IA64ISelLowering.cpp
@@ -121,8 +121,8 @@ IA64TargetLowering::IA64TargetLowering(TargetMachine &TM)
computeRegisterProperties();
setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
- addLegalFPImmediate(+0.0);
- addLegalFPImmediate(+1.0);
+ addLegalFPImmediate(APFloat(+0.0));
+ addLegalFPImmediate(APFloat(+1.0));
}
const char *IA64TargetLowering::getTargetNodeName(unsigned Opcode) const {
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 7ebac836dd..99fc9bae63 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -296,7 +296,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
// cases we handle.
setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
- addLegalFPImmediate(+0.0); // xorps / xorpd
+ addLegalFPImmediate(APFloat(+0.0)); // xorps / xorpd
// Conversions to long double (in X87) go through memory.
setConvertAction(MVT::f32, MVT::f80, Expand);
@@ -327,10 +327,10 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
- addLegalFPImmediate(+0.0); // FLD0
- addLegalFPImmediate(+1.0); // FLD1
- addLegalFPImmediate(-0.0); // FLD0/FCHS
- addLegalFPImmediate(-1.0); // FLD1/FCHS
+ addLegalFPImmediate(APFloat(+0.0)); // FLD0
+ addLegalFPImmediate(APFloat(+1.0)); // FLD1
+ addLegalFPImmediate(APFloat(-0.0)); // FLD0/FCHS
+ addLegalFPImmediate(APFloat(-1.0)); // FLD1/FCHS
}
// Long double always uses X87.
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 04689e4c98..8e3d946ec4 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -240,15 +240,24 @@ ConstantInt *ConstantInt::get(const APInt& V) {
ConstantFP::ConstantFP(const Type *Ty, double V)
- : Constant(Ty, ConstantFPVal, 0, 0), Val(APFloat(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
+ if (Ty==Type::FloatTy)
+ assert(&V.getSemantics()==&APFloat::IEEEsingle);
+ else
+ assert(&V.getSemantics()==&APFloat::IEEEdouble);
}
bool ConstantFP::isNullValue() const {
return Val.isZero() && !Val.isNegative();
}
-bool ConstantFP::isExactlyValue(double V) const {
- return Val.bitwiseIsEqual(APFloat(V));
+bool ConstantFP::isExactlyValue(const APFloat& V) const {
+ return Val.bitwiseIsEqual(V);
}
namespace {
@@ -289,14 +298,14 @@ ConstantFP *ConstantFP::get(const Type *Ty, double V) {
DenseMapAPFloatKeyInfo::KeyTy Key(APFloat((float)V));
ConstantFP *&Slot = (*FPConstants)[Key];
if (Slot) return Slot;
- return Slot = new ConstantFP(Ty, (float)V);
+ 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, V);
+ 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.");
@@ -305,6 +314,18 @@ ConstantFP *ConstantFP::get(const Type *Ty, double V) {
}
}
+ConstantFP *ConstantFP::get(const Type *Ty, const APFloat& V) {
+ // temporary
+ if (Ty==Type::FloatTy)
+ assert(&V.getSemantics()==&APFloat::IEEEsingle);
+ else
+ assert(&V.getSemantics()==&APFloat::IEEEdouble);
+
+ DenseMapAPFloatKeyInfo::KeyTy Key(V);
+ ConstantFP *&Slot = (*FPConstants)[Key];
+ if (Slot) return Slot;
+ return Slot = new ConstantFP(Ty, V);
+}
//===----------------------------------------------------------------------===//
// ConstantXXX Classes
@@ -699,14 +720,24 @@ bool ConstantInt::isValueValidForType(const Type *Ty, int64_t Val) {
return (Val >= Min && Val <= Max);
}
-bool ConstantFP::isValueValidForType(const Type *Ty, double Val) {
+bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) {
+ // convert modifies in place, so make a copy.
+ APFloat Val2 = APFloat(Val);
switch (Ty->getTypeID()) {
default:
return false; // These can't be represented as floating point!
- // TODO: Figure out how to test if we can use a shorter type instead!
+ // FIXME rounding mode needs to be more flexible
case Type::FloatTyID:
+ return &Val2.getSemantics() == &APFloat::IEEEsingle ||
+ Val2.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven) ==
+ APFloat::opOK;
case Type::DoubleTyID:
+ return &Val2.getSemantics() == &APFloat::IEEEsingle ||
+ &Val2.getSemantics() == &APFloat::IEEEdouble ||
+ Val2.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven) ==
+ APFloat::opOK;
+ // TODO: Figure out how to test if we can use a shorter type instead!
case Type::X86_FP80TyID:
case Type::PPC_FP128TyID:
case Type::FP128TyID: