1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

Make APFloat constructor require explicit semantics.

Previously we tried to infer it from the bit width size, with an added
IsIEEE argument for the PPC/IEEE 128-bit case, which had a default
value. This default value allowed bugs to creep in, where it was
inappropriate.

llvm-svn: 173138
This commit is contained in:
Tim Northover 2013-01-22 09:46:31 +00:00
parent 72a924a1ad
commit 52ba1e77cb
17 changed files with 159 additions and 102 deletions

View File

@ -184,9 +184,9 @@ namespace llvm {
APFloat(const fltSemantics &, integerPart); APFloat(const fltSemantics &, integerPart);
APFloat(const fltSemantics &, fltCategory, bool negative); APFloat(const fltSemantics &, fltCategory, bool negative);
APFloat(const fltSemantics &, uninitializedTag); APFloat(const fltSemantics &, uninitializedTag);
APFloat(const fltSemantics &, const APInt &);
explicit APFloat(double d); explicit APFloat(double d);
explicit APFloat(float f); explicit APFloat(float f);
explicit APFloat(const APInt &, bool isIEEE = false);
APFloat(const APFloat &); APFloat(const APFloat &);
~APFloat(); ~APFloat();
@ -423,7 +423,7 @@ namespace llvm {
APInt convertQuadrupleAPFloatToAPInt() const; APInt convertQuadrupleAPFloatToAPInt() const;
APInt convertF80LongDoubleAPFloatToAPInt() const; APInt convertF80LongDoubleAPFloatToAPInt() const;
APInt convertPPCDoubleDoubleAPFloatToAPInt() const; APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
void initFromAPInt(const APInt& api, bool isIEEE = false); void initFromAPInt(const fltSemantics *Sem, const APInt& api);
void initFromHalfAPInt(const APInt& api); void initFromHalfAPInt(const APInt& api);
void initFromFloatAPInt(const APInt& api); void initFromFloatAPInt(const APInt& api);
void initFromDoubleAPInt(const APInt& api); void initFromDoubleAPInt(const APInt& api);

View File

@ -935,6 +935,20 @@ public:
} }
} }
/// Returns an APFloat semantics tag appropriate for the given type. If VT is
/// a vector type, the element semantics are returned.
static const fltSemantics &EVTToAPFloatSemantics(EVT VT) {
switch (VT.getScalarType().getSimpleVT().SimpleTy) {
default: llvm_unreachable("Unknown FP format");
case MVT::f16: return APFloat::IEEEhalf;
case MVT::f32: return APFloat::IEEEsingle;
case MVT::f64: return APFloat::IEEEdouble;
case MVT::f80: return APFloat::x87DoubleExtended;
case MVT::f128: return APFloat::IEEEquad;
case MVT::ppcf128: return APFloat::PPCDoubleDouble;
}
}
/// AssignOrdering - Assign an order to the SDNode. /// AssignOrdering - Assign an order to the SDNode.
void AssignOrdering(const SDNode *SD, unsigned Order); void AssignOrdering(const SDNode *SD, unsigned Order);

View File

@ -15,8 +15,10 @@
#ifndef LLVM_IR_TYPE_H #ifndef LLVM_IR_TYPE_H
#define LLVM_IR_TYPE_H #define LLVM_IR_TYPE_H
#include "llvm/ADT/APFloat.h"
#include "llvm/Support/Casting.h" #include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm { namespace llvm {
@ -162,6 +164,18 @@ public:
getTypeID() == PPC_FP128TyID; getTypeID() == PPC_FP128TyID;
} }
const fltSemantics &getFltSemantics() const {
switch (getTypeID()) {
case HalfTyID: return APFloat::IEEEhalf;
case FloatTyID: return APFloat::IEEEsingle;
case DoubleTyID: return APFloat::IEEEdouble;
case X86_FP80TyID: return APFloat::x87DoubleExtended;
case FP128TyID: return APFloat::IEEEquad;
case PPC_FP128TyID: return APFloat::PPCDoubleDouble;
default: llvm_unreachable("Invalid floating type");
}
}
/// isX86_MMXTy - Return true if this is X86 MMX. /// isX86_MMXTy - Return true if this is X86 MMX.
bool isX86_MMXTy() const { return getTypeID() == X86_MMXTyID; } bool isX86_MMXTy() const { return getTypeID() == X86_MMXTyID; }

View File

@ -1337,7 +1337,7 @@ llvm::ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands,
case Intrinsic::ctpop: case Intrinsic::ctpop:
return ConstantInt::get(Ty, Op->getValue().countPopulation()); return ConstantInt::get(Ty, Op->getValue().countPopulation());
case Intrinsic::convert_from_fp16: { case Intrinsic::convert_from_fp16: {
APFloat Val(Op->getValue()); APFloat Val(APFloat::IEEEhalf, Op->getValue());
bool lost = false; bool lost = false;
APFloat::opStatus status = APFloat::opStatus status =

View File

@ -713,20 +713,21 @@ lltok::Kind LLLexer::Lex0x() {
case 'K': case 'K':
// F80HexFPConstant - x87 long double in hexadecimal format (10 bytes) // F80HexFPConstant - x87 long double in hexadecimal format (10 bytes)
FP80HexToIntPair(TokStart+3, CurPtr, Pair); FP80HexToIntPair(TokStart+3, CurPtr, Pair);
APFloatVal = APFloat(APInt(80, Pair)); APFloatVal = APFloat(APFloat::x87DoubleExtended, APInt(80, Pair));
return lltok::APFloat; return lltok::APFloat;
case 'L': case 'L':
// F128HexFPConstant - IEEE 128-bit in hexadecimal format (16 bytes) // F128HexFPConstant - IEEE 128-bit in hexadecimal format (16 bytes)
HexToIntPair(TokStart+3, CurPtr, Pair); HexToIntPair(TokStart+3, CurPtr, Pair);
APFloatVal = APFloat(APInt(128, Pair), true); APFloatVal = APFloat(APFloat::IEEEquad, APInt(128, Pair));
return lltok::APFloat; return lltok::APFloat;
case 'M': case 'M':
// PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes) // PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes)
HexToIntPair(TokStart+3, CurPtr, Pair); HexToIntPair(TokStart+3, CurPtr, Pair);
APFloatVal = APFloat(APInt(128, Pair)); APFloatVal = APFloat(APFloat::PPCDoubleDouble, APInt(128, Pair));
return lltok::APFloat; return lltok::APFloat;
case 'H': case 'H':
APFloatVal = APFloat(APInt(16,HexIntToVal(TokStart+3, CurPtr))); APFloatVal = APFloat(APFloat::IEEEhalf,
APInt(16,HexIntToVal(TokStart+3, CurPtr)));
return lltok::APFloat; return lltok::APFloat;
} }
} }

View File

@ -986,21 +986,27 @@ bool BitcodeReader::ParseConstants() {
if (Record.empty()) if (Record.empty())
return Error("Invalid FLOAT record"); return Error("Invalid FLOAT record");
if (CurTy->isHalfTy()) if (CurTy->isHalfTy())
V = ConstantFP::get(Context, APFloat(APInt(16, (uint16_t)Record[0]))); V = ConstantFP::get(Context, APFloat(APFloat::IEEEhalf,
APInt(16, (uint16_t)Record[0])));
else if (CurTy->isFloatTy()) else if (CurTy->isFloatTy())
V = ConstantFP::get(Context, APFloat(APInt(32, (uint32_t)Record[0]))); V = ConstantFP::get(Context, APFloat(APFloat::IEEEsingle,
APInt(32, (uint32_t)Record[0])));
else if (CurTy->isDoubleTy()) else if (CurTy->isDoubleTy())
V = ConstantFP::get(Context, APFloat(APInt(64, Record[0]))); V = ConstantFP::get(Context, APFloat(APFloat::IEEEdouble,
APInt(64, Record[0])));
else if (CurTy->isX86_FP80Ty()) { else if (CurTy->isX86_FP80Ty()) {
// Bits are not stored the same way as a normal i80 APInt, compensate. // Bits are not stored the same way as a normal i80 APInt, compensate.
uint64_t Rearrange[2]; uint64_t Rearrange[2];
Rearrange[0] = (Record[1] & 0xffffLL) | (Record[0] << 16); Rearrange[0] = (Record[1] & 0xffffLL) | (Record[0] << 16);
Rearrange[1] = Record[0] >> 48; Rearrange[1] = Record[0] >> 48;
V = ConstantFP::get(Context, APFloat(APInt(80, Rearrange))); V = ConstantFP::get(Context, APFloat(APFloat::x87DoubleExtended,
APInt(80, Rearrange)));
} else if (CurTy->isFP128Ty()) } else if (CurTy->isFP128Ty())
V = ConstantFP::get(Context, APFloat(APInt(128, Record), true)); V = ConstantFP::get(Context, APFloat(APFloat::IEEEquad,
APInt(128, Record)));
else if (CurTy->isPPC_FP128Ty()) else if (CurTy->isPPC_FP128Ty())
V = ConstantFP::get(Context, APFloat(APInt(128, Record))); V = ConstantFP::get(Context, APFloat(APFloat::PPCDoubleDouble,
APInt(128, Record)));
else else
V = UndefValue::get(CurTy); V = UndefValue::get(CurTy);
break; break;

View File

@ -2805,7 +2805,8 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
SDValue True, False; SDValue True, False;
EVT VT = Node->getOperand(0).getValueType(); EVT VT = Node->getOperand(0).getValueType();
EVT NVT = Node->getValueType(0); EVT NVT = Node->getValueType(0);
APFloat apf(APInt::getNullValue(VT.getSizeInBits())); APFloat apf(DAG.EVTToAPFloatSemantics(VT),
APInt::getNullValue(VT.getSizeInBits()));
APInt x = APInt::getSignBit(NVT.getSizeInBits()); APInt x = APInt::getSignBit(NVT.getSizeInBits());
(void)apf.convertFromAPInt(x, false, APFloat::rmNearestTiesToEven); (void)apf.convertFromAPInt(x, false, APFloat::rmNearestTiesToEven);
Tmp1 = DAG.getConstantFP(apf, VT); Tmp1 = DAG.getConstantFP(apf, VT);

View File

@ -813,9 +813,11 @@ void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo,
assert(NVT.getSizeInBits() == integerPartWidth && assert(NVT.getSizeInBits() == integerPartWidth &&
"Do not know how to expand this float constant!"); "Do not know how to expand this float constant!");
APInt C = cast<ConstantFPSDNode>(N)->getValueAPF().bitcastToAPInt(); APInt C = cast<ConstantFPSDNode>(N)->getValueAPF().bitcastToAPInt();
Lo = DAG.getConstantFP(APFloat(APInt(integerPartWidth, C.getRawData()[1])), Lo = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT),
APInt(integerPartWidth, C.getRawData()[1])),
NVT); NVT);
Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, C.getRawData()[0])), Hi = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT),
APInt(integerPartWidth, C.getRawData()[0])),
NVT); NVT);
} }
@ -987,7 +989,8 @@ void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo,
SDValue &Hi) { SDValue &Hi) {
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
Hi = DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), NVT, N->getOperand(0)); Hi = DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), NVT, N->getOperand(0));
Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); Lo = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT),
APInt(NVT.getSizeInBits(), 0)), NVT);
} }
void DAGTypeLegalizer::ExpandFloatRes_FPOW(SDNode *N, void DAGTypeLegalizer::ExpandFloatRes_FPOW(SDNode *N,
@ -1082,7 +1085,8 @@ void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo,
Chain = Hi.getValue(1); Chain = Hi.getValue(1);
// The low part is zero. // The low part is zero.
Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); Lo = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT),
APInt(NVT.getSizeInBits(), 0)), NVT);
// Modified the chain - switch anything that used the old chain to use the // Modified the chain - switch anything that used the old chain to use the
// new one. // new one.
@ -1106,7 +1110,8 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
// The integer can be represented exactly in an f64. // The integer can be represented exactly in an f64.
Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl, Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl,
MVT::i32, Src); MVT::i32, Src);
Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); Lo = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT),
APInt(NVT.getSizeInBits(), 0)), NVT);
Hi = DAG.getNode(ISD::SINT_TO_FP, dl, NVT, Src); Hi = DAG.getNode(ISD::SINT_TO_FP, dl, NVT, Src);
} else { } else {
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
@ -1152,7 +1157,8 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
} }
Lo = DAG.getNode(ISD::FADD, dl, VT, Hi, Lo = DAG.getNode(ISD::FADD, dl, VT, Hi,
DAG.getConstantFP(APFloat(APInt(128, Parts)), DAG.getConstantFP(APFloat(APFloat::PPCDoubleDouble,
APInt(128, Parts)),
MVT::ppcf128)); MVT::ppcf128));
Lo = DAG.getNode(ISD::SELECT_CC, dl, VT, Src, DAG.getConstant(0, SrcVT), Lo = DAG.getNode(ISD::SELECT_CC, dl, VT, Src, DAG.getConstant(0, SrcVT),
Lo, Hi, DAG.getCondCode(ISD::SETLT)); Lo, Hi, DAG.getCondCode(ISD::SETLT));
@ -1304,7 +1310,7 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) {
assert(N->getOperand(0).getValueType() == MVT::ppcf128 && assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
"Logic only correct for ppcf128!"); "Logic only correct for ppcf128!");
const uint64_t TwoE31[] = {0x41e0000000000000LL, 0}; const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
APFloat APF = APFloat(APInt(128, TwoE31)); APFloat APF = APFloat(APFloat::PPCDoubleDouble, APInt(128, TwoE31));
SDValue Tmp = DAG.getConstantFP(APF, MVT::ppcf128); SDValue Tmp = DAG.getConstantFP(APF, MVT::ppcf128);
// X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
// FIXME: generated code sucks. // FIXME: generated code sucks.

View File

@ -2767,17 +2767,6 @@ SDValue DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) {
return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), InL); return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), InL);
} }
static const fltSemantics *EVTToAPFloatSemantics(EVT VT) {
switch (VT.getSimpleVT().SimpleTy) {
default: llvm_unreachable("Unknown FP format");
case MVT::f32: return &APFloat::IEEEsingle;
case MVT::f64: return &APFloat::IEEEdouble;
case MVT::f80: return &APFloat::x87DoubleExtended;
case MVT::f128: return &APFloat::IEEEquad;
case MVT::ppcf128: return &APFloat::PPCDoubleDouble;
}
}
SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) { SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) {
SDValue Op = N->getOperand(0); SDValue Op = N->getOperand(0);
EVT SrcVT = Op.getValueType(); EVT SrcVT = Op.getValueType();
@ -2787,8 +2776,8 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) {
// The following optimization is valid only if every value in SrcVT (when // The following optimization is valid only if every value in SrcVT (when
// treated as signed) is representable in DstVT. Check that the mantissa // treated as signed) is representable in DstVT. Check that the mantissa
// size of DstVT is >= than the number of bits in SrcVT -1. // size of DstVT is >= than the number of bits in SrcVT -1.
const fltSemantics *sem = EVTToAPFloatSemantics(DstVT); const fltSemantics &sem = DAG.EVTToAPFloatSemantics(DstVT);
if (APFloat::semanticsPrecision(*sem) >= SrcVT.getSizeInBits()-1 && if (APFloat::semanticsPrecision(sem) >= SrcVT.getSizeInBits()-1 &&
TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) == TargetLowering::Custom){ TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) == TargetLowering::Custom){
// Do a signed conversion then adjust the result. // Do a signed conversion then adjust the result.
SDValue SignedConv = DAG.getNode(ISD::SINT_TO_FP, dl, DstVT, Op); SDValue SignedConv = DAG.getNode(ISD::SINT_TO_FP, dl, DstVT, Op);

View File

@ -60,18 +60,6 @@ static SDVTList makeVTList(const EVT *VTs, unsigned NumVTs) {
return Res; return Res;
} }
static const fltSemantics *EVTToAPFloatSemantics(EVT VT) {
switch (VT.getSimpleVT().SimpleTy) {
default: llvm_unreachable("Unknown FP format");
case MVT::f16: return &APFloat::IEEEhalf;
case MVT::f32: return &APFloat::IEEEsingle;
case MVT::f64: return &APFloat::IEEEdouble;
case MVT::f80: return &APFloat::x87DoubleExtended;
case MVT::f128: return &APFloat::IEEEquad;
case MVT::ppcf128: return &APFloat::PPCDoubleDouble;
}
}
// Default null implementations of the callbacks. // Default null implementations of the callbacks.
void SelectionDAG::DAGUpdateListener::NodeDeleted(SDNode*, SDNode*) {} void SelectionDAG::DAGUpdateListener::NodeDeleted(SDNode*, SDNode*) {}
void SelectionDAG::DAGUpdateListener::NodeUpdated(SDNode*) {} void SelectionDAG::DAGUpdateListener::NodeUpdated(SDNode*) {}
@ -95,7 +83,8 @@ bool ConstantFPSDNode::isValueValidForType(EVT VT,
// convert modifies in place, so make a copy. // convert modifies in place, so make a copy.
APFloat Val2 = APFloat(Val); APFloat Val2 = APFloat(Val);
bool losesInfo; bool losesInfo;
(void) Val2.convert(*EVTToAPFloatSemantics(VT), APFloat::rmNearestTiesToEven, (void) Val2.convert(SelectionDAG::EVTToAPFloatSemantics(VT),
APFloat::rmNearestTiesToEven,
&losesInfo); &losesInfo);
return !losesInfo; return !losesInfo;
} }
@ -1081,7 +1070,7 @@ SDValue SelectionDAG::getConstantFP(double Val, EVT VT, bool isTarget) {
EltVT==MVT::f16) { EltVT==MVT::f16) {
bool ignored; bool ignored;
APFloat apf = APFloat(Val); APFloat apf = APFloat(Val);
apf.convert(*EVTToAPFloatSemantics(EltVT), APFloat::rmNearestTiesToEven, apf.convert(EVTToAPFloatSemantics(EltVT), APFloat::rmNearestTiesToEven,
&ignored); &ignored);
return getConstantFP(apf, VT, isTarget); return getConstantFP(apf, VT, isTarget);
} else } else
@ -2442,7 +2431,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL,
return getConstant(Val.zextOrTrunc(VT.getSizeInBits()), VT); return getConstant(Val.zextOrTrunc(VT.getSizeInBits()), VT);
case ISD::UINT_TO_FP: case ISD::UINT_TO_FP:
case ISD::SINT_TO_FP: { case ISD::SINT_TO_FP: {
APFloat apf(APInt::getNullValue(VT.getSizeInBits())); APFloat apf(EVTToAPFloatSemantics(VT),
APInt::getNullValue(VT.getSizeInBits()));
(void)apf.convertFromAPInt(Val, (void)apf.convertFromAPInt(Val,
Opcode==ISD::SINT_TO_FP, Opcode==ISD::SINT_TO_FP,
APFloat::rmNearestTiesToEven); APFloat::rmNearestTiesToEven);
@ -2450,9 +2440,9 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL,
} }
case ISD::BITCAST: case ISD::BITCAST:
if (VT == MVT::f32 && C->getValueType(0) == MVT::i32) if (VT == MVT::f32 && C->getValueType(0) == MVT::i32)
return getConstantFP(APFloat(Val), VT); return getConstantFP(APFloat(APFloat::IEEEsingle, Val), VT);
else if (VT == MVT::f64 && C->getValueType(0) == MVT::i64) else if (VT == MVT::f64 && C->getValueType(0) == MVT::i64)
return getConstantFP(APFloat(Val), VT); return getConstantFP(APFloat(APFloat::IEEEdouble, Val), VT);
break; break;
case ISD::BSWAP: case ISD::BSWAP:
return getConstant(Val.byteSwap(), VT); return getConstant(Val.byteSwap(), VT);
@ -2499,7 +2489,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL,
bool ignored; bool ignored;
// This can return overflow, underflow, or inexact; we don't care. // This can return overflow, underflow, or inexact; we don't care.
// FIXME need to be more flexible about rounding mode. // FIXME need to be more flexible about rounding mode.
(void)V.convert(*EVTToAPFloatSemantics(VT), (void)V.convert(EVTToAPFloatSemantics(VT),
APFloat::rmNearestTiesToEven, &ignored); APFloat::rmNearestTiesToEven, &ignored);
return getConstantFP(V, VT); return getConstantFP(V, VT);
} }
@ -3084,7 +3074,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT,
bool ignored; bool ignored;
// This can return overflow, underflow, or inexact; we don't care. // This can return overflow, underflow, or inexact; we don't care.
// FIXME need to be more flexible about rounding mode. // FIXME need to be more flexible about rounding mode.
(void)V.convert(*EVTToAPFloatSemantics(VT), (void)V.convert(EVTToAPFloatSemantics(VT),
APFloat::rmNearestTiesToEven, &ignored); APFloat::rmNearestTiesToEven, &ignored);
return getConstantFP(V, VT); return getConstantFP(V, VT);
} }
@ -3338,7 +3328,7 @@ static SDValue getMemsetValue(SDValue Value, EVT VT, SelectionDAG &DAG,
APInt Val = SplatByte(NumBits, C->getZExtValue() & 255); APInt Val = SplatByte(NumBits, C->getZExtValue() & 255);
if (VT.isInteger()) if (VT.isInteger())
return DAG.getConstant(Val, VT); return DAG.getConstant(Val, VT);
return DAG.getConstantFP(APFloat(Val), VT); return DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(VT), Val), VT);
} }
Value = DAG.getNode(ISD::ZERO_EXTEND, dl, VT, Value); Value = DAG.getNode(ISD::ZERO_EXTEND, dl, VT, Value);

View File

@ -3694,7 +3694,8 @@ GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI,
/// getF32Constant - Get 32-bit floating point constant. /// getF32Constant - Get 32-bit floating point constant.
static SDValue static SDValue
getF32Constant(SelectionDAG &DAG, unsigned Flt) { getF32Constant(SelectionDAG &DAG, unsigned Flt) {
return DAG.getConstantFP(APFloat(APInt(32, Flt)), MVT::f32); return DAG.getConstantFP(APFloat(APFloat::IEEEsingle, APInt(32, Flt)),
MVT::f32);
} }
/// expandExp - Lower an exp intrinsic. Handles the special sequences for /// expandExp - Lower an exp intrinsic. Handles the special sequences for

View File

@ -632,7 +632,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
else if (Op0->getType()->isDoubleTy()) else if (Op0->getType()->isDoubleTy())
GV.IntVal = APIntOps::RoundDoubleToAPInt(GV.DoubleVal, BitWidth); GV.IntVal = APIntOps::RoundDoubleToAPInt(GV.DoubleVal, BitWidth);
else if (Op0->getType()->isX86_FP80Ty()) { else if (Op0->getType()->isX86_FP80Ty()) {
APFloat apf = APFloat(GV.IntVal); APFloat apf = APFloat(APFloat::x87DoubleExtended, GV.IntVal);
uint64_t v; uint64_t v;
bool ignored; bool ignored;
(void)apf.convertToInteger(&v, BitWidth, (void)apf.convertToInteger(&v, BitWidth,
@ -751,27 +751,32 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
case Type::X86_FP80TyID: case Type::X86_FP80TyID:
case Type::PPC_FP128TyID: case Type::PPC_FP128TyID:
case Type::FP128TyID: { case Type::FP128TyID: {
APFloat apfLHS = APFloat(LHS.IntVal); const fltSemantics &Sem = CE->getOperand(0)->getType()->getFltSemantics();
APFloat apfLHS = APFloat(Sem, LHS.IntVal);
switch (CE->getOpcode()) { switch (CE->getOpcode()) {
default: llvm_unreachable("Invalid long double opcode"); default: llvm_unreachable("Invalid long double opcode");
case Instruction::FAdd: case Instruction::FAdd:
apfLHS.add(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven); apfLHS.add(APFloat(Sem, RHS.IntVal), APFloat::rmNearestTiesToEven);
GV.IntVal = apfLHS.bitcastToAPInt(); GV.IntVal = apfLHS.bitcastToAPInt();
break; break;
case Instruction::FSub: case Instruction::FSub:
apfLHS.subtract(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven); apfLHS.subtract(APFloat(Sem, RHS.IntVal),
APFloat::rmNearestTiesToEven);
GV.IntVal = apfLHS.bitcastToAPInt(); GV.IntVal = apfLHS.bitcastToAPInt();
break; break;
case Instruction::FMul: case Instruction::FMul:
apfLHS.multiply(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven); apfLHS.multiply(APFloat(Sem, RHS.IntVal),
APFloat::rmNearestTiesToEven);
GV.IntVal = apfLHS.bitcastToAPInt(); GV.IntVal = apfLHS.bitcastToAPInt();
break; break;
case Instruction::FDiv: case Instruction::FDiv:
apfLHS.divide(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven); apfLHS.divide(APFloat(Sem, RHS.IntVal),
APFloat::rmNearestTiesToEven);
GV.IntVal = apfLHS.bitcastToAPInt(); GV.IntVal = apfLHS.bitcastToAPInt();
break; break;
case Instruction::FRem: case Instruction::FRem:
apfLHS.mod(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven); apfLHS.mod(APFloat(Sem, RHS.IntVal),
APFloat::rmNearestTiesToEven);
GV.IntVal = apfLHS.bitcastToAPInt(); GV.IntVal = apfLHS.bitcastToAPInt();
break; break;
} }

View File

@ -522,7 +522,8 @@ GenericValue JIT::runFunction(Function *F,
case Type::PPC_FP128TyID: case Type::PPC_FP128TyID:
case Type::X86_FP80TyID: case Type::X86_FP80TyID:
case Type::FP128TyID: case Type::FP128TyID:
C = ConstantFP::get(F->getContext(), APFloat(AV.IntVal)); C = ConstantFP::get(F->getContext(), APFloat(ArgTy->getFltSemantics(),
AV.IntVal));
break; break;
case Type::PointerTyID: case Type::PointerTyID:
void *ArgPtr = GVTOP(AV); void *ArgPtr = GVTOP(AV);

View File

@ -168,8 +168,8 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) {
if (DestTy->isFloatingPointTy()) if (DestTy->isFloatingPointTy())
return ConstantFP::get(DestTy->getContext(), return ConstantFP::get(DestTy->getContext(),
APFloat(CI->getValue(), APFloat(DestTy->getFltSemantics(),
!DestTy->isPPC_FP128Ty())); CI->getValue()));
// Otherwise, can't fold this (vector?) // Otherwise, can't fold this (vector?)
return 0; return 0;
@ -647,8 +647,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
case Instruction::SIToFP: case Instruction::SIToFP:
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
APInt api = CI->getValue(); APInt api = CI->getValue();
APFloat apf(APInt::getNullValue(DestTy->getPrimitiveSizeInBits()), APFloat apf(DestTy->getFltSemantics(),
!DestTy->isPPC_FP128Ty() /* isEEEE */); APInt::getNullValue(DestTy->getPrimitiveSizeInBits()));
(void)apf.convertFromAPInt(api, (void)apf.convertFromAPInt(api,
opc==Instruction::SIToFP, opc==Instruction::SIToFP,
APFloat::rmNearestTiesToEven); APFloat::rmNearestTiesToEven);

View File

@ -119,7 +119,8 @@ Constant *Constant::getNullValue(Type *Ty) {
APFloat::getZero(APFloat::IEEEquad)); APFloat::getZero(APFloat::IEEEquad));
case Type::PPC_FP128TyID: case Type::PPC_FP128TyID:
return ConstantFP::get(Ty->getContext(), return ConstantFP::get(Ty->getContext(),
APFloat(APInt::getNullValue(128))); APFloat(APFloat::PPCDoubleDouble,
APInt::getNullValue(128)));
case Type::PointerTyID: case Type::PointerTyID:
return ConstantPointerNull::get(cast<PointerType>(Ty)); return ConstantPointerNull::get(cast<PointerType>(Ty));
case Type::StructTyID: case Type::StructTyID:

View File

@ -3013,7 +3013,7 @@ APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api)
// Unless we have a special case, add in second double. // Unless we have a special case, add in second double.
if (category == fcNormal) { if (category == fcNormal) {
APFloat v(APInt(64, i2)); APFloat v(IEEEdouble, APInt(64, i2));
fs = v.convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo); fs = v.convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
assert(fs == opOK && !losesInfo); assert(fs == opOK && !losesInfo);
(void)fs; (void)fs;
@ -3166,27 +3166,43 @@ APFloat::initFromHalfAPInt(const APInt & api)
/// isIEEE argument distinguishes between PPC128 and IEEE128 (not meaningful /// isIEEE argument distinguishes between PPC128 and IEEE128 (not meaningful
/// when the size is anything else). /// when the size is anything else).
void void
APFloat::initFromAPInt(const APInt& api, bool isIEEE) APFloat::initFromAPInt(const fltSemantics* Sem, const APInt& api)
{ {
if (api.getBitWidth() == 16) if (Sem == &IEEEhalf)
return initFromHalfAPInt(api); return initFromHalfAPInt(api);
else if (api.getBitWidth() == 32) if (Sem == &IEEEsingle)
return initFromFloatAPInt(api); return initFromFloatAPInt(api);
else if (api.getBitWidth()==64) if (Sem == &IEEEdouble)
return initFromDoubleAPInt(api); return initFromDoubleAPInt(api);
else if (api.getBitWidth()==80) if (Sem == &x87DoubleExtended)
return initFromF80LongDoubleAPInt(api); return initFromF80LongDoubleAPInt(api);
else if (api.getBitWidth()==128) if (Sem == &IEEEquad)
return (isIEEE ? return initFromQuadrupleAPInt(api);
initFromQuadrupleAPInt(api) : initFromPPCDoubleDoubleAPInt(api)); if (Sem == &PPCDoubleDouble)
else return initFromPPCDoubleDoubleAPInt(api);
llvm_unreachable(0);
llvm_unreachable(0);
} }
APFloat APFloat
APFloat::getAllOnesValue(unsigned BitWidth, bool isIEEE) APFloat::getAllOnesValue(unsigned BitWidth, bool isIEEE)
{ {
return APFloat(APInt::getAllOnesValue(BitWidth), isIEEE); switch (BitWidth) {
case 16:
return APFloat(IEEEhalf, APInt::getAllOnesValue(BitWidth));
case 32:
return APFloat(IEEEsingle, APInt::getAllOnesValue(BitWidth));
case 64:
return APFloat(IEEEdouble, APInt::getAllOnesValue(BitWidth));
case 80:
return APFloat(x87DoubleExtended, APInt::getAllOnesValue(BitWidth));
case 128:
if (isIEEE)
return APFloat(IEEEquad, APInt::getAllOnesValue(BitWidth));
return APFloat(PPCDoubleDouble, APInt::getAllOnesValue(BitWidth));
default:
llvm_unreachable("Unknown floating bit width");
}
} }
APFloat APFloat::getLargest(const fltSemantics &Sem, bool Negative) { APFloat APFloat::getLargest(const fltSemantics &Sem, bool Negative) {
@ -3244,16 +3260,16 @@ APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) {
return Val; return Val;
} }
APFloat::APFloat(const APInt& api, bool isIEEE) { APFloat::APFloat(const fltSemantics &Sem, const APInt &API) {
initFromAPInt(api, isIEEE); initFromAPInt(&Sem, API);
} }
APFloat::APFloat(float f) { APFloat::APFloat(float f) {
initFromAPInt(APInt::floatToBits(f)); initFromAPInt(&IEEEsingle, APInt::floatToBits(f));
} }
APFloat::APFloat(double d) { APFloat::APFloat(double d) {
initFromAPInt(APInt::doubleToBits(d)); initFromAPInt(&IEEEdouble, APInt::doubleToBits(d));
} }
namespace { namespace {

View File

@ -8010,9 +8010,11 @@ SDValue X86TargetLowering::LowerUINT_TO_FP_i64(SDValue Op,
SmallVector<Constant*,2> CV1; SmallVector<Constant*,2> CV1;
CV1.push_back( CV1.push_back(
ConstantFP::get(*Context, APFloat(APInt(64, 0x4330000000000000ULL)))); ConstantFP::get(*Context, APFloat(APFloat::IEEEdouble,
APInt(64, 0x4330000000000000ULL))));
CV1.push_back( CV1.push_back(
ConstantFP::get(*Context, APFloat(APInt(64, 0x4530000000000000ULL)))); ConstantFP::get(*Context, APFloat(APFloat::IEEEdouble,
APInt(64, 0x4530000000000000ULL))));
Constant *C1 = ConstantVector::get(CV1); Constant *C1 = ConstantVector::get(CV1);
SDValue CPIdx1 = DAG.getConstantPool(C1, getPointerTy(), 16); SDValue CPIdx1 = DAG.getConstantPool(C1, getPointerTy(), 16);
@ -8565,9 +8567,11 @@ SDValue X86TargetLowering::LowerFABS(SDValue Op, SelectionDAG &DAG) const {
} }
Constant *C; Constant *C;
if (EltVT == MVT::f64) if (EltVT == MVT::f64)
C = ConstantFP::get(*Context, APFloat(APInt(64, ~(1ULL << 63)))); C = ConstantFP::get(*Context, APFloat(APFloat::IEEEdouble,
APInt(64, ~(1ULL << 63))));
else else
C = ConstantFP::get(*Context, APFloat(APInt(32, ~(1U << 31)))); C = ConstantFP::get(*Context, APFloat(APFloat::IEEEsingle,
APInt(32, ~(1U << 31))));
C = ConstantVector::getSplat(NumElts, C); C = ConstantVector::getSplat(NumElts, C);
SDValue CPIdx = DAG.getConstantPool(C, getPointerTy()); SDValue CPIdx = DAG.getConstantPool(C, getPointerTy());
unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
@ -8597,9 +8601,11 @@ SDValue X86TargetLowering::LowerFNEG(SDValue Op, SelectionDAG &DAG) const {
} }
Constant *C; Constant *C;
if (EltVT == MVT::f64) if (EltVT == MVT::f64)
C = ConstantFP::get(*Context, APFloat(APInt(64, 1ULL << 63))); C = ConstantFP::get(*Context, APFloat(APFloat::IEEEdouble,
APInt(64, 1ULL << 63)));
else else
C = ConstantFP::get(*Context, APFloat(APInt(32, 1U << 31))); C = ConstantFP::get(*Context, APFloat(APFloat::IEEEsingle,
APInt(32, 1U << 31)));
C = ConstantVector::getSplat(NumElts, C); C = ConstantVector::getSplat(NumElts, C);
SDValue CPIdx = DAG.getConstantPool(C, getPointerTy()); SDValue CPIdx = DAG.getConstantPool(C, getPointerTy());
unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
@ -8643,13 +8649,15 @@ SDValue X86TargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const {
// First get the sign bit of second operand. // First get the sign bit of second operand.
SmallVector<Constant*,4> CV; SmallVector<Constant*,4> CV;
if (SrcVT == MVT::f64) { if (SrcVT == MVT::f64) {
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(64, 1ULL << 63)))); const fltSemantics &Sem = APFloat::IEEEdouble;
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(64, 0)))); CV.push_back(ConstantFP::get(*Context, APFloat(Sem, APInt(64, 1ULL << 63))));
CV.push_back(ConstantFP::get(*Context, APFloat(Sem, APInt(64, 0))));
} else { } else {
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, 1U << 31)))); const fltSemantics &Sem = APFloat::IEEEsingle;
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, 0)))); CV.push_back(ConstantFP::get(*Context, APFloat(Sem, APInt(32, 1U << 31))));
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, 0)))); CV.push_back(ConstantFP::get(*Context, APFloat(Sem, APInt(32, 0))));
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, 0)))); CV.push_back(ConstantFP::get(*Context, APFloat(Sem, APInt(32, 0))));
CV.push_back(ConstantFP::get(*Context, APFloat(Sem, APInt(32, 0))));
} }
Constant *C = ConstantVector::get(CV); Constant *C = ConstantVector::get(CV);
SDValue CPIdx = DAG.getConstantPool(C, getPointerTy(), 16); SDValue CPIdx = DAG.getConstantPool(C, getPointerTy(), 16);
@ -8672,13 +8680,17 @@ SDValue X86TargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const {
// Clear first operand sign bit. // Clear first operand sign bit.
CV.clear(); CV.clear();
if (VT == MVT::f64) { if (VT == MVT::f64) {
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(64, ~(1ULL << 63))))); const fltSemantics &Sem = APFloat::IEEEdouble;
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(64, 0)))); CV.push_back(ConstantFP::get(*Context, APFloat(Sem,
APInt(64, ~(1ULL << 63)))));
CV.push_back(ConstantFP::get(*Context, APFloat(Sem, APInt(64, 0))));
} else { } else {
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, ~(1U << 31))))); const fltSemantics &Sem = APFloat::IEEEsingle;
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, 0)))); CV.push_back(ConstantFP::get(*Context, APFloat(Sem,
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, 0)))); APInt(32, ~(1U << 31)))));
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, 0)))); CV.push_back(ConstantFP::get(*Context, APFloat(Sem, APInt(32, 0))));
CV.push_back(ConstantFP::get(*Context, APFloat(Sem, APInt(32, 0))));
CV.push_back(ConstantFP::get(*Context, APFloat(Sem, APInt(32, 0))));
} }
C = ConstantVector::get(CV); C = ConstantVector::get(CV);
CPIdx = DAG.getConstantPool(C, getPointerTy(), 16); CPIdx = DAG.getConstantPool(C, getPointerTy(), 16);