aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp41
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp28
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp5
-rw-r--r--lib/Support/APInt.cpp2
-rw-r--r--lib/Support/FoldingSet.cpp6
-rw-r--r--lib/Target/CBackend/CBackend.cpp3
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp32
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp8
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp9
-rw-r--r--lib/VMCore/Constants.cpp25
10 files changed, 108 insertions, 51 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index da55eafdb2..d709169d35 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -486,15 +486,23 @@ static SDOperand ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP,
// double.
MVT::ValueType VT = CFP->getValueType(0);
bool isDouble = VT == MVT::f64;
- ConstantFP *LLVMC = ConstantFP::get(isDouble ? Type::DoubleTy :
- Type::FloatTy, CFP->getValueAPF());
+ ConstantFP *LLVMC = ConstantFP::get(VT==MVT::f64 ? Type::DoubleTy :
+ VT==MVT::f32 ? Type::FloatTy :
+ VT==MVT::f80 ? Type::X86_FP80Ty :
+ VT==MVT::f128 ? Type::FP128Ty :
+ VT==MVT::ppcf128 ? Type::PPC_FP128Ty :
+ Type::VoidTy, // error
+ CFP->getValueAPF());
if (!UseCP) {
+ if (VT!=MVT::f64 && VT!=MVT::f32)
+ assert(0 && "Invalid type expansion");
return DAG.getConstant(LLVMC->getValueAPF().convertToAPInt().getZExtValue(),
isDouble ? MVT::i64 : MVT::i32);
}
if (isDouble && CFP->isValueValidForType(MVT::f32, CFP->getValueAPF()) &&
// Only do this if the target has a native EXTLOAD instruction from f32.
+ // Do not try to be clever about long doubles (so far)
TLI.isLoadXLegal(ISD::EXTLOAD, MVT::f32)) {
LLVMC = cast<ConstantFP>(ConstantExpr::getFPTrunc(LLVMC,Type::FloatTy));
VT = MVT::f32;
@@ -1976,19 +1984,22 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
// to phase ordering between legalized code and the dag combiner. This
// probably means that we need to integrate dag combiner and legalizer
// together.
- if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(ST->getValue())) {
+ // We generally can't do this one for long doubles.
+ if (ConstantFPSDNode *CFP =dyn_cast<ConstantFPSDNode>(ST->getValue())) {
if (CFP->getValueType(0) == MVT::f32) {
Tmp3 = DAG.getConstant((uint32_t)CFP->getValueAPF().
convertToAPInt().getZExtValue(),
MVT::i32);
- } else {
- assert(CFP->getValueType(0) == MVT::f64 && "Unknown FP type!");
+ Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ SVOffset, isVolatile, Alignment);
+ break;
+ } else if (CFP->getValueType(0) == MVT::f64) {
Tmp3 = DAG.getConstant(CFP->getValueAPF().convertToAPInt().
getZExtValue(), MVT::i64);
+ Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ SVOffset, isVolatile, Alignment);
+ break;
}
- Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
- SVOffset, isVolatile, Alignment);
- break;
}
switch (getTypeAction(ST->getStoredVT())) {
@@ -4609,12 +4620,16 @@ ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) {
SDOperand FudgeInReg;
if (DestTy == MVT::f32)
FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, NULL, 0);
- else {
- assert(DestTy == MVT::f64 && "Unexpected conversion");
+ else if (DestTy == MVT::f64)
// FIXME: Avoid the extend by construction the right constantpool?
FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(),
CPIdx, NULL, 0, MVT::f32);
- }
+ else if (DestTy == MVT::f80)
+ FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, MVT::f80, DAG.getEntryNode(),
+ CPIdx, NULL, 0, MVT::f32);
+ else
+ assert(0 && "Unexpected conversion");
+
MVT::ValueType SCVT = SignedConv.getValueType();
if (SCVT != DestTy) {
// Destination type needs to be expanded as well. The FADD now we are
@@ -4722,9 +4737,11 @@ SDOperand SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
if (DestVT == MVT::f64) {
// do nothing
Result = Sub;
- } else {
+ } else if (DestVT == MVT::f32) {
// if f32 then cast to f32
Result = DAG.getNode(ISD::FP_ROUND, MVT::f32, Sub);
+ } else if (DestVT == MVT::f80) {
+ Result = DAG.getNode(ISD::FP_EXTEND, MVT::f80, Sub);
}
return Result;
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 0defc12e05..3744c4ad66 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -322,13 +322,7 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, SDNode *N) {
break;
case ISD::TargetConstantFP:
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);
+ ID.AddAPFloat(cast<ConstantFPSDNode>(N)->getValueAPF());
break;
}
case ISD::TargetGlobalAddress:
@@ -709,25 +703,21 @@ SDOperand SelectionDAG::getConstantFP(const APFloat& V, MVT::ValueType VT,
MVT::ValueType EltVT =
MVT::isVector(VT) ? MVT::getVectorElementType(VT) : VT;
- 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);
+ ID.AddAPFloat(V);
void *IP = 0;
SDNode *N = NULL;
if ((N = CSEMap.FindNodeOrInsertPos(ID, IP)))
if (!MVT::isVector(VT))
return SDOperand(N, 0);
if (!N) {
- N = new ConstantFPSDNode(isTarget,
- isDouble ? APFloat(Val) : APFloat((float)Val), EltVT);
+ N = new ConstantFPSDNode(isTarget, V, EltVT);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
}
@@ -3724,9 +3714,15 @@ void SDNode::dump(const SelectionDAG *G) const {
if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(this)) {
cerr << "<" << CSDN->getValue() << ">";
} else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(this)) {
- cerr << "<" << (&CSDN->getValueAPF().getSemantics()==&APFloat::IEEEsingle ?
- CSDN->getValueAPF().convertToFloat() :
- CSDN->getValueAPF().convertToDouble()) << ">";
+ if (&CSDN->getValueAPF().getSemantics()==&APFloat::IEEEsingle)
+ cerr << "<" << CSDN->getValueAPF().convertToFloat() << ">";
+ else if (&CSDN->getValueAPF().getSemantics()==&APFloat::IEEEdouble)
+ cerr << "<" << CSDN->getValueAPF().convertToDouble() << ">";
+ else {
+ cerr << "<APFloat(";
+ CSDN->getValueAPF().convertToAPInt().dump();
+ cerr << ")>";
+ }
} else if (const GlobalAddressSDNode *GADN =
dyn_cast<GlobalAddressSDNode>(this)) {
int offset = GADN->getOffset();
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 561b303f70..14691ee485 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -2004,8 +2004,7 @@ 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,
- ElTy==Type::FloatTy ? APFloat(-0.0f) : APFloat(-0.0)));
+ std::vector<Constant*> NZ(VL, ConstantFP::getNegativeZero(ElTy));
Constant *CNZ = ConstantVector::get(&NZ[0], NZ.size());
if (CV == CNZ) {
SDOperand Op2 = getValue(I.getOperand(1));
@@ -2017,7 +2016,7 @@ void SelectionDAGLowering::visitSub(User &I) {
}
if (Ty->isFloatingPoint()) {
if (ConstantFP *CFP = dyn_cast<ConstantFP>(I.getOperand(0)))
- if (CFP->isExactlyValue(-0.0)) {
+ if (CFP->isExactlyValue(ConstantFP::getNegativeZero(Ty)->getValueAPF())) {
SDOperand Op2 = getValue(I.getOperand(1));
setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2));
return;
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index 277a0b0c11..15de08ed05 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -2009,7 +2009,7 @@ void APInt::dump() const
cerr << pVal[i-1] << " ";
}
cerr << " U(" << this->toStringUnsigned(10) << ") S("
- << this->toStringSigned(10) << ")\n" << std::setbase(10);
+ << this->toStringSigned(10) << ")" << std::setbase(10);
}
#endif
diff --git a/lib/Support/FoldingSet.cpp b/lib/Support/FoldingSet.cpp
index 0ccb3a6cc3..70daad9a61 100644
--- a/lib/Support/FoldingSet.cpp
+++ b/lib/Support/FoldingSet.cpp
@@ -56,6 +56,12 @@ void FoldingSetImpl::NodeID::AddFloat(float F) {
void FoldingSetImpl::NodeID::AddDouble(double D) {
AddInteger(DoubleToBits(D));
}
+void FoldingSetImpl::NodeID::AddAPFloat(const APFloat& apf) {
+ APInt api = apf.convertToAPInt();
+ const uint64_t *p = api.getRawData();
+ for (int i=0; i<api.getNumWords(); i++)
+ AddInteger(*p++);
+}
void FoldingSetImpl::NodeID::AddString(const std::string &String) {
unsigned Size = String.size();
Bits.push_back(Size);
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index 9fc30c45da..5f6d5905bf 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -604,6 +604,9 @@ void CWriter::printConstantVector(ConstantVector *CP) {
// only deal in IEEE FP).
//
static bool isFPCSafeToPrint(const ConstantFP *CFP) {
+ // Do long doubles the hard way for now.
+ if (CFP->getType()!=Type::FloatTy && CFP->getType()!=Type::DoubleTy)
+ return false;
APFloat APF = APFloat(CFP->getValueAPF()); // copy
if (CFP->getType()==Type::FloatTy)
APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven);
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index b073887bd1..55f37a6584 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -99,9 +99,11 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote);
setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote);
// SSE has no i16 to fp conversion, only i32
- if (X86ScalarSSE)
+ if (X86ScalarSSE) {
setOperationAction(ISD::SINT_TO_FP , MVT::i16 , Promote);
- else {
+ // f32 and f64 cases are Legal, f80 case is not
+ setOperationAction(ISD::SINT_TO_FP , MVT::i32 , Custom);
+ } else {
setOperationAction(ISD::SINT_TO_FP , MVT::i16 , Custom);
setOperationAction(ISD::SINT_TO_FP , MVT::i32 , Custom);
}
@@ -119,6 +121,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
if (X86ScalarSSE) {
setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Promote);
+ // f32 and f64 cases are Legal, f80 case is not
+ setOperationAction(ISD::FP_TO_SINT , MVT::i32 , Custom);
} else {
setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Custom);
setOperationAction(ISD::FP_TO_SINT , MVT::i32 , Custom);
@@ -189,11 +193,13 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
setOperationAction(ISD::SELECT , MVT::i32 , Custom);
setOperationAction(ISD::SELECT , MVT::f32 , Custom);
setOperationAction(ISD::SELECT , MVT::f64 , Custom);
+ setOperationAction(ISD::SELECT , MVT::f80 , Custom);
setOperationAction(ISD::SETCC , MVT::i8 , Custom);
setOperationAction(ISD::SETCC , MVT::i16 , Custom);
setOperationAction(ISD::SETCC , MVT::i32 , Custom);
setOperationAction(ISD::SETCC , MVT::f32 , Custom);
setOperationAction(ISD::SETCC , MVT::f64 , Custom);
+ setOperationAction(ISD::SETCC , MVT::f80 , Custom);
if (Subtarget->is64Bit()) {
setOperationAction(ISD::SELECT , MVT::i64 , Custom);
setOperationAction(ISD::SETCC , MVT::i64 , Custom);
@@ -334,6 +340,9 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
// Long double always uses X87.
addRegisterClass(MVT::f80, X86::RFP80RegisterClass);
+ setOperationAction(ISD::UNDEF, MVT::f80, Expand);
+ setOperationAction(ISD::FCOPYSIGN, MVT::f80, Expand);
+ setOperationAction(ISD::ConstantFP, MVT::f80, Expand);
// First set operation action for all vector types to expand. Then we
// will selectively turn on ones that can be effectively codegen'd.
@@ -3326,9 +3335,14 @@ SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
SDOperand Chain = DAG.getStore(DAG.getEntryNode(), Op.getOperand(0),
StackSlot, NULL, 0);
+ // These are really Legal; caller falls through into that case.
+ if (SrcVT==MVT::i32 && Op.getValueType() != MVT::f80 && X86ScalarSSE)
+ return Result;
+
// Build the FILD
SDVTList Tys;
- if (X86ScalarSSE)
+ bool useSSE = X86ScalarSSE && Op.getValueType() != MVT::f80;
+ if (useSSE)
Tys = DAG.getVTList(MVT::f64, MVT::Other, MVT::Flag);
else
Tys = DAG.getVTList(Op.getValueType(), MVT::Other);
@@ -3336,10 +3350,10 @@ SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
Ops.push_back(Chain);
Ops.push_back(StackSlot);
Ops.push_back(DAG.getValueType(SrcVT));
- Result = DAG.getNode(X86ScalarSSE ? X86ISD::FILD_FLAG :X86ISD::FILD,
+ Result = DAG.getNode(useSSE ? X86ISD::FILD_FLAG :X86ISD::FILD,
Tys, &Ops[0], Ops.size());
- if (X86ScalarSSE) {
+ if (useSSE) {
Chain = Result.getValue(1);
SDOperand InFlag = Result.getValue(2);
@@ -3368,11 +3382,17 @@ SDOperand X86TargetLowering::LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) {
"Unknown FP_TO_SINT to lower!");
// We lower FP->sint64 into FISTP64, followed by a load, all to a temporary
// stack slot.
+ SDOperand Result;
MachineFunction &MF = DAG.getMachineFunction();
unsigned MemSize = MVT::getSizeInBits(Op.getValueType())/8;
int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize);
SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
+ // These are really Legal.
+ if (Op.getValueType() == MVT::i32 && X86ScalarSSE &&
+ Op.getOperand(0).getValueType() != MVT::f80)
+ return Result;
+
unsigned Opc;
switch (Op.getValueType()) {
default: assert(0 && "Invalid FP_TO_SINT to lower!");
@@ -3383,7 +3403,7 @@ SDOperand X86TargetLowering::LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) {
SDOperand Chain = DAG.getEntryNode();
SDOperand Value = Op.getOperand(0);
- if (X86ScalarSSE) {
+ if (X86ScalarSSE && Op.getOperand(0).getValueType() != MVT::f80) {
assert(Op.getValueType() == MVT::i64 && "Invalid FP_TO_SINT to lower!");
Chain = DAG.getStore(Chain, Value, StackSlot, NULL, 0);
SDVTList Tys = DAG.getVTList(Op.getOperand(0).getValueType(), MVT::Other);
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index 557f07e8b4..4a8c275bc5 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -168,7 +168,11 @@ void X86RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
Opc = X86::MOV32_mr;
} else if (RC == &X86::GR16_RegClass) {
Opc = X86::MOV16_mr;
+ } else if (RC == &X86::RFP80RegClass) {
+ Opc = X86::ST_FpP80m; // pops
} else if (RC == &X86::RFP64RegClass || RC == &X86::RSTRegClass) {
+ /// FIXME spilling long double values as 64 bit does not work.
+ /// We need RST80, unfortunately.
Opc = X86::ST_Fp64m;
} else if (RC == &X86::RFP32RegClass) {
Opc = X86::ST_Fp32m;
@@ -205,6 +209,8 @@ void X86RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
Opc = X86::MOV32_rm;
} else if (RC == &X86::GR16_RegClass) {
Opc = X86::MOV16_rm;
+ } else if (RC == &X86::RFP80RegClass) {
+ Opc = X86::LD_Fp80m;
} else if (RC == &X86::RFP64RegClass || RC == &X86::RSTRegClass) {
Opc = X86::LD_Fp64m;
} else if (RC == &X86::RFP32RegClass) {
@@ -245,6 +251,8 @@ void X86RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
Opc = X86::MOV_Fp3232;
} else if (RC == &X86::RFP64RegClass || RC == &X86::RSTRegClass) {
Opc = X86::MOV_Fp6464;
+ } else if (RC == &X86::RFP80RegClass) {
+ Opc = X86::MOV_Fp8080;
} else if (RC == &X86::FR32RegClass) {
Opc = X86::FsMOVAPSrr;
} else if (RC == &X86::FR64RegClass) {
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 0343635270..ab6262b47e 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -1949,7 +1949,8 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
if (RHSC->isNullValue())
return ReplaceInstUsesWith(I, LHS);
} else if (ConstantFP *CFP = dyn_cast<ConstantFP>(RHSC)) {
- if (CFP->isExactlyValue(-0.0))
+ if (CFP->isExactlyValue(ConstantFP::getNegativeZero
+ (I.getType())->getValueAPF()))
return ReplaceInstUsesWith(I, LHS);
}
@@ -2349,8 +2350,10 @@ 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->isExactlyValue(1.0))
- return ReplaceInstUsesWith(I, Op0); // Eliminate 'mul double %X, 1.0'
+ // We need a better interface for long double here.
+ if (Op1->getType() == Type::FloatTy || Op1->getType() == Type::DoubleTy)
+ if (Op1F->isExactlyValue(1.0))
+ return ReplaceInstUsesWith(I, Op0); // Eliminate 'mul double %X, 1.0'
}
if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0))
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index c546045454..2bcd7b68b7 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -103,17 +103,19 @@ bool Constant::ContainsRelocations() const {
// Static constructor to create a '0' constant of arbitrary type...
Constant *Constant::getNullValue(const Type *Ty) {
+ static uint64_t zero[2] = {0, 0};
switch (Ty->getTypeID()) {
case Type::IntegerTyID:
return ConstantInt::get(Ty, 0);
case Type::FloatTyID:
- return ConstantFP::get(Ty, APFloat(0.0f));
+ return ConstantFP::get(Ty, APFloat(APInt(32, 0)));
case Type::DoubleTyID:
- return ConstantFP::get(Ty, APFloat(0.0));
+ return ConstantFP::get(Ty, APFloat(APInt(64, 0)));
case Type::X86_FP80TyID:
- case Type::PPC_FP128TyID:
+ return ConstantFP::get(Ty, APFloat(APInt(80, 2, zero)));
case Type::FP128TyID:
- return ConstantFP::get(Ty, APFloat(0.0)); //FIXME
+ case Type::PPC_FP128TyID:
+ return ConstantFP::get(Ty, APFloat(APInt(128, 2, zero)));
case Type::PointerTyID:
return ConstantPointerNull::get(cast<PointerType>(Ty));
case Type::StructTyID:
@@ -259,6 +261,12 @@ bool ConstantFP::isNullValue() const {
return Val.isZero() && !Val.isNegative();
}
+ConstantFP *ConstantFP::getNegativeZero(const Type *Ty) {
+ APFloat apf = cast <ConstantFP>(Constant::getNullValue(Ty))->getValueAPF();
+ apf.changeSign();
+ return ConstantFP::get(Ty, apf);
+}
+
bool ConstantFP::isExactlyValue(const APFloat& V) const {
return Val.bitwiseIsEqual(V);
}
@@ -1925,15 +1933,12 @@ 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(),
- PTy->getElementType()==Type::FloatTy ?
- APFloat(-0.0f) : APFloat(0.0)));
+ ConstantFP::getNegativeZero(PTy->getElementType()));
return ConstantVector::get(PTy, zeros);
}
- if (Ty->isFloatingPoint())
- return ConstantFP::get(Ty, Ty==Type::FloatTy ? APFloat(-0.0f) :
- APFloat(-0.0));
+ if (Ty->isFloatingPoint())
+ return ConstantFP::getNegativeZero(Ty);
return Constant::getNullValue(Ty);
}