mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00: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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173138 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dc89ed7da3
commit
0a29cb0454
@ -184,9 +184,9 @@ namespace llvm {
|
||||
APFloat(const fltSemantics &, integerPart);
|
||||
APFloat(const fltSemantics &, fltCategory, bool negative);
|
||||
APFloat(const fltSemantics &, uninitializedTag);
|
||||
APFloat(const fltSemantics &, const APInt &);
|
||||
explicit APFloat(double d);
|
||||
explicit APFloat(float f);
|
||||
explicit APFloat(const APInt &, bool isIEEE = false);
|
||||
APFloat(const APFloat &);
|
||||
~APFloat();
|
||||
|
||||
@ -423,7 +423,7 @@ namespace llvm {
|
||||
APInt convertQuadrupleAPFloatToAPInt() const;
|
||||
APInt convertF80LongDoubleAPFloatToAPInt() 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 initFromFloatAPInt(const APInt& api);
|
||||
void initFromDoubleAPInt(const APInt& api);
|
||||
|
@ -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.
|
||||
void AssignOrdering(const SDNode *SD, unsigned Order);
|
||||
|
||||
|
@ -15,8 +15,10 @@
|
||||
#ifndef LLVM_IR_TYPE_H
|
||||
#define LLVM_IR_TYPE_H
|
||||
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -162,6 +164,18 @@ public:
|
||||
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.
|
||||
bool isX86_MMXTy() const { return getTypeID() == X86_MMXTyID; }
|
||||
|
||||
|
@ -1337,7 +1337,7 @@ llvm::ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands,
|
||||
case Intrinsic::ctpop:
|
||||
return ConstantInt::get(Ty, Op->getValue().countPopulation());
|
||||
case Intrinsic::convert_from_fp16: {
|
||||
APFloat Val(Op->getValue());
|
||||
APFloat Val(APFloat::IEEEhalf, Op->getValue());
|
||||
|
||||
bool lost = false;
|
||||
APFloat::opStatus status =
|
||||
|
@ -713,20 +713,21 @@ lltok::Kind LLLexer::Lex0x() {
|
||||
case 'K':
|
||||
// F80HexFPConstant - x87 long double in hexadecimal format (10 bytes)
|
||||
FP80HexToIntPair(TokStart+3, CurPtr, Pair);
|
||||
APFloatVal = APFloat(APInt(80, Pair));
|
||||
APFloatVal = APFloat(APFloat::x87DoubleExtended, APInt(80, Pair));
|
||||
return lltok::APFloat;
|
||||
case 'L':
|
||||
// F128HexFPConstant - IEEE 128-bit in hexadecimal format (16 bytes)
|
||||
HexToIntPair(TokStart+3, CurPtr, Pair);
|
||||
APFloatVal = APFloat(APInt(128, Pair), true);
|
||||
APFloatVal = APFloat(APFloat::IEEEquad, APInt(128, Pair));
|
||||
return lltok::APFloat;
|
||||
case 'M':
|
||||
// PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes)
|
||||
HexToIntPair(TokStart+3, CurPtr, Pair);
|
||||
APFloatVal = APFloat(APInt(128, Pair));
|
||||
APFloatVal = APFloat(APFloat::PPCDoubleDouble, APInt(128, Pair));
|
||||
return lltok::APFloat;
|
||||
case 'H':
|
||||
APFloatVal = APFloat(APInt(16,HexIntToVal(TokStart+3, CurPtr)));
|
||||
APFloatVal = APFloat(APFloat::IEEEhalf,
|
||||
APInt(16,HexIntToVal(TokStart+3, CurPtr)));
|
||||
return lltok::APFloat;
|
||||
}
|
||||
}
|
||||
|
@ -986,21 +986,27 @@ bool BitcodeReader::ParseConstants() {
|
||||
if (Record.empty())
|
||||
return Error("Invalid FLOAT record");
|
||||
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())
|
||||
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())
|
||||
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()) {
|
||||
// Bits are not stored the same way as a normal i80 APInt, compensate.
|
||||
uint64_t Rearrange[2];
|
||||
Rearrange[0] = (Record[1] & 0xffffLL) | (Record[0] << 16);
|
||||
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())
|
||||
V = ConstantFP::get(Context, APFloat(APInt(128, Record), true));
|
||||
V = ConstantFP::get(Context, APFloat(APFloat::IEEEquad,
|
||||
APInt(128, Record)));
|
||||
else if (CurTy->isPPC_FP128Ty())
|
||||
V = ConstantFP::get(Context, APFloat(APInt(128, Record)));
|
||||
V = ConstantFP::get(Context, APFloat(APFloat::PPCDoubleDouble,
|
||||
APInt(128, Record)));
|
||||
else
|
||||
V = UndefValue::get(CurTy);
|
||||
break;
|
||||
|
@ -2805,7 +2805,8 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
|
||||
SDValue True, False;
|
||||
EVT VT = Node->getOperand(0).getValueType();
|
||||
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());
|
||||
(void)apf.convertFromAPInt(x, false, APFloat::rmNearestTiesToEven);
|
||||
Tmp1 = DAG.getConstantFP(apf, VT);
|
||||
|
@ -813,9 +813,11 @@ void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo,
|
||||
assert(NVT.getSizeInBits() == integerPartWidth &&
|
||||
"Do not know how to expand this float constant!");
|
||||
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);
|
||||
Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, C.getRawData()[0])),
|
||||
Hi = DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(NVT),
|
||||
APInt(integerPartWidth, C.getRawData()[0])),
|
||||
NVT);
|
||||
}
|
||||
|
||||
@ -987,7 +989,8 @@ void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo,
|
||||
SDValue &Hi) {
|
||||
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(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,
|
||||
@ -1082,7 +1085,8 @@ void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo,
|
||||
Chain = Hi.getValue(1);
|
||||
|
||||
// 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
|
||||
// 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.
|
||||
Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl,
|
||||
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);
|
||||
} else {
|
||||
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,
|
||||
DAG.getConstantFP(APFloat(APInt(128, Parts)),
|
||||
DAG.getConstantFP(APFloat(APFloat::PPCDoubleDouble,
|
||||
APInt(128, Parts)),
|
||||
MVT::ppcf128));
|
||||
Lo = DAG.getNode(ISD::SELECT_CC, dl, VT, Src, DAG.getConstant(0, SrcVT),
|
||||
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 &&
|
||||
"Logic only correct for ppcf128!");
|
||||
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);
|
||||
// X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
|
||||
// FIXME: generated code sucks.
|
||||
|
@ -2767,17 +2767,6 @@ SDValue DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) {
|
||||
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 Op = N->getOperand(0);
|
||||
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
|
||||
// treated as signed) is representable in DstVT. Check that the mantissa
|
||||
// size of DstVT is >= than the number of bits in SrcVT -1.
|
||||
const fltSemantics *sem = EVTToAPFloatSemantics(DstVT);
|
||||
if (APFloat::semanticsPrecision(*sem) >= SrcVT.getSizeInBits()-1 &&
|
||||
const fltSemantics &sem = DAG.EVTToAPFloatSemantics(DstVT);
|
||||
if (APFloat::semanticsPrecision(sem) >= SrcVT.getSizeInBits()-1 &&
|
||||
TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) == TargetLowering::Custom){
|
||||
// Do a signed conversion then adjust the result.
|
||||
SDValue SignedConv = DAG.getNode(ISD::SINT_TO_FP, dl, DstVT, Op);
|
||||
|
@ -60,18 +60,6 @@ static SDVTList makeVTList(const EVT *VTs, unsigned NumVTs) {
|
||||
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.
|
||||
void SelectionDAG::DAGUpdateListener::NodeDeleted(SDNode*, SDNode*) {}
|
||||
void SelectionDAG::DAGUpdateListener::NodeUpdated(SDNode*) {}
|
||||
@ -95,7 +83,8 @@ bool ConstantFPSDNode::isValueValidForType(EVT VT,
|
||||
// convert modifies in place, so make a copy.
|
||||
APFloat Val2 = APFloat(Val);
|
||||
bool losesInfo;
|
||||
(void) Val2.convert(*EVTToAPFloatSemantics(VT), APFloat::rmNearestTiesToEven,
|
||||
(void) Val2.convert(SelectionDAG::EVTToAPFloatSemantics(VT),
|
||||
APFloat::rmNearestTiesToEven,
|
||||
&losesInfo);
|
||||
return !losesInfo;
|
||||
}
|
||||
@ -1081,7 +1070,7 @@ SDValue SelectionDAG::getConstantFP(double Val, EVT VT, bool isTarget) {
|
||||
EltVT==MVT::f16) {
|
||||
bool ignored;
|
||||
APFloat apf = APFloat(Val);
|
||||
apf.convert(*EVTToAPFloatSemantics(EltVT), APFloat::rmNearestTiesToEven,
|
||||
apf.convert(EVTToAPFloatSemantics(EltVT), APFloat::rmNearestTiesToEven,
|
||||
&ignored);
|
||||
return getConstantFP(apf, VT, isTarget);
|
||||
} else
|
||||
@ -2442,7 +2431,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL,
|
||||
return getConstant(Val.zextOrTrunc(VT.getSizeInBits()), VT);
|
||||
case ISD::UINT_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,
|
||||
Opcode==ISD::SINT_TO_FP,
|
||||
APFloat::rmNearestTiesToEven);
|
||||
@ -2450,9 +2440,9 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL,
|
||||
}
|
||||
case ISD::BITCAST:
|
||||
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)
|
||||
return getConstantFP(APFloat(Val), VT);
|
||||
return getConstantFP(APFloat(APFloat::IEEEdouble, Val), VT);
|
||||
break;
|
||||
case ISD::BSWAP:
|
||||
return getConstant(Val.byteSwap(), VT);
|
||||
@ -2499,7 +2489,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL,
|
||||
bool ignored;
|
||||
// This can return overflow, underflow, or inexact; we don't care.
|
||||
// FIXME need to be more flexible about rounding mode.
|
||||
(void)V.convert(*EVTToAPFloatSemantics(VT),
|
||||
(void)V.convert(EVTToAPFloatSemantics(VT),
|
||||
APFloat::rmNearestTiesToEven, &ignored);
|
||||
return getConstantFP(V, VT);
|
||||
}
|
||||
@ -3084,7 +3074,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT,
|
||||
bool ignored;
|
||||
// This can return overflow, underflow, or inexact; we don't care.
|
||||
// FIXME need to be more flexible about rounding mode.
|
||||
(void)V.convert(*EVTToAPFloatSemantics(VT),
|
||||
(void)V.convert(EVTToAPFloatSemantics(VT),
|
||||
APFloat::rmNearestTiesToEven, &ignored);
|
||||
return getConstantFP(V, VT);
|
||||
}
|
||||
@ -3338,7 +3328,7 @@ static SDValue getMemsetValue(SDValue Value, EVT VT, SelectionDAG &DAG,
|
||||
APInt Val = SplatByte(NumBits, C->getZExtValue() & 255);
|
||||
if (VT.isInteger())
|
||||
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);
|
||||
|
@ -3694,7 +3694,8 @@ GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI,
|
||||
/// getF32Constant - Get 32-bit floating point constant.
|
||||
static SDValue
|
||||
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
|
||||
|
@ -632,7 +632,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
|
||||
else if (Op0->getType()->isDoubleTy())
|
||||
GV.IntVal = APIntOps::RoundDoubleToAPInt(GV.DoubleVal, BitWidth);
|
||||
else if (Op0->getType()->isX86_FP80Ty()) {
|
||||
APFloat apf = APFloat(GV.IntVal);
|
||||
APFloat apf = APFloat(APFloat::x87DoubleExtended, GV.IntVal);
|
||||
uint64_t v;
|
||||
bool ignored;
|
||||
(void)apf.convertToInteger(&v, BitWidth,
|
||||
@ -751,27 +751,32 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
|
||||
case Type::X86_FP80TyID:
|
||||
case Type::PPC_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()) {
|
||||
default: llvm_unreachable("Invalid long double opcode");
|
||||
case Instruction::FAdd:
|
||||
apfLHS.add(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven);
|
||||
apfLHS.add(APFloat(Sem, RHS.IntVal), APFloat::rmNearestTiesToEven);
|
||||
GV.IntVal = apfLHS.bitcastToAPInt();
|
||||
break;
|
||||
case Instruction::FSub:
|
||||
apfLHS.subtract(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven);
|
||||
apfLHS.subtract(APFloat(Sem, RHS.IntVal),
|
||||
APFloat::rmNearestTiesToEven);
|
||||
GV.IntVal = apfLHS.bitcastToAPInt();
|
||||
break;
|
||||
case Instruction::FMul:
|
||||
apfLHS.multiply(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven);
|
||||
apfLHS.multiply(APFloat(Sem, RHS.IntVal),
|
||||
APFloat::rmNearestTiesToEven);
|
||||
GV.IntVal = apfLHS.bitcastToAPInt();
|
||||
break;
|
||||
case Instruction::FDiv:
|
||||
apfLHS.divide(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven);
|
||||
apfLHS.divide(APFloat(Sem, RHS.IntVal),
|
||||
APFloat::rmNearestTiesToEven);
|
||||
GV.IntVal = apfLHS.bitcastToAPInt();
|
||||
break;
|
||||
case Instruction::FRem:
|
||||
apfLHS.mod(APFloat(RHS.IntVal), APFloat::rmNearestTiesToEven);
|
||||
apfLHS.mod(APFloat(Sem, RHS.IntVal),
|
||||
APFloat::rmNearestTiesToEven);
|
||||
GV.IntVal = apfLHS.bitcastToAPInt();
|
||||
break;
|
||||
}
|
||||
|
@ -522,7 +522,8 @@ GenericValue JIT::runFunction(Function *F,
|
||||
case Type::PPC_FP128TyID:
|
||||
case Type::X86_FP80TyID:
|
||||
case Type::FP128TyID:
|
||||
C = ConstantFP::get(F->getContext(), APFloat(AV.IntVal));
|
||||
C = ConstantFP::get(F->getContext(), APFloat(ArgTy->getFltSemantics(),
|
||||
AV.IntVal));
|
||||
break;
|
||||
case Type::PointerTyID:
|
||||
void *ArgPtr = GVTOP(AV);
|
||||
|
@ -168,8 +168,8 @@ static Constant *FoldBitCast(Constant *V, Type *DestTy) {
|
||||
|
||||
if (DestTy->isFloatingPointTy())
|
||||
return ConstantFP::get(DestTy->getContext(),
|
||||
APFloat(CI->getValue(),
|
||||
!DestTy->isPPC_FP128Ty()));
|
||||
APFloat(DestTy->getFltSemantics(),
|
||||
CI->getValue()));
|
||||
|
||||
// Otherwise, can't fold this (vector?)
|
||||
return 0;
|
||||
@ -647,8 +647,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
|
||||
case Instruction::SIToFP:
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
|
||||
APInt api = CI->getValue();
|
||||
APFloat apf(APInt::getNullValue(DestTy->getPrimitiveSizeInBits()),
|
||||
!DestTy->isPPC_FP128Ty() /* isEEEE */);
|
||||
APFloat apf(DestTy->getFltSemantics(),
|
||||
APInt::getNullValue(DestTy->getPrimitiveSizeInBits()));
|
||||
(void)apf.convertFromAPInt(api,
|
||||
opc==Instruction::SIToFP,
|
||||
APFloat::rmNearestTiesToEven);
|
||||
|
@ -119,7 +119,8 @@ Constant *Constant::getNullValue(Type *Ty) {
|
||||
APFloat::getZero(APFloat::IEEEquad));
|
||||
case Type::PPC_FP128TyID:
|
||||
return ConstantFP::get(Ty->getContext(),
|
||||
APFloat(APInt::getNullValue(128)));
|
||||
APFloat(APFloat::PPCDoubleDouble,
|
||||
APInt::getNullValue(128)));
|
||||
case Type::PointerTyID:
|
||||
return ConstantPointerNull::get(cast<PointerType>(Ty));
|
||||
case Type::StructTyID:
|
||||
|
@ -3013,7 +3013,7 @@ APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api)
|
||||
|
||||
// Unless we have a special case, add in second double.
|
||||
if (category == fcNormal) {
|
||||
APFloat v(APInt(64, i2));
|
||||
APFloat v(IEEEdouble, APInt(64, i2));
|
||||
fs = v.convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
|
||||
assert(fs == opOK && !losesInfo);
|
||||
(void)fs;
|
||||
@ -3166,27 +3166,43 @@ APFloat::initFromHalfAPInt(const APInt & api)
|
||||
/// isIEEE argument distinguishes between PPC128 and IEEE128 (not meaningful
|
||||
/// when the size is anything else).
|
||||
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);
|
||||
else if (api.getBitWidth() == 32)
|
||||
if (Sem == &IEEEsingle)
|
||||
return initFromFloatAPInt(api);
|
||||
else if (api.getBitWidth()==64)
|
||||
if (Sem == &IEEEdouble)
|
||||
return initFromDoubleAPInt(api);
|
||||
else if (api.getBitWidth()==80)
|
||||
if (Sem == &x87DoubleExtended)
|
||||
return initFromF80LongDoubleAPInt(api);
|
||||
else if (api.getBitWidth()==128)
|
||||
return (isIEEE ?
|
||||
initFromQuadrupleAPInt(api) : initFromPPCDoubleDoubleAPInt(api));
|
||||
else
|
||||
llvm_unreachable(0);
|
||||
if (Sem == &IEEEquad)
|
||||
return initFromQuadrupleAPInt(api);
|
||||
if (Sem == &PPCDoubleDouble)
|
||||
return initFromPPCDoubleDoubleAPInt(api);
|
||||
|
||||
llvm_unreachable(0);
|
||||
}
|
||||
|
||||
APFloat
|
||||
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) {
|
||||
@ -3244,16 +3260,16 @@ APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) {
|
||||
return Val;
|
||||
}
|
||||
|
||||
APFloat::APFloat(const APInt& api, bool isIEEE) {
|
||||
initFromAPInt(api, isIEEE);
|
||||
APFloat::APFloat(const fltSemantics &Sem, const APInt &API) {
|
||||
initFromAPInt(&Sem, API);
|
||||
}
|
||||
|
||||
APFloat::APFloat(float f) {
|
||||
initFromAPInt(APInt::floatToBits(f));
|
||||
initFromAPInt(&IEEEsingle, APInt::floatToBits(f));
|
||||
}
|
||||
|
||||
APFloat::APFloat(double d) {
|
||||
initFromAPInt(APInt::doubleToBits(d));
|
||||
initFromAPInt(&IEEEdouble, APInt::doubleToBits(d));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -8010,9 +8010,11 @@ SDValue X86TargetLowering::LowerUINT_TO_FP_i64(SDValue Op,
|
||||
|
||||
SmallVector<Constant*,2> CV1;
|
||||
CV1.push_back(
|
||||
ConstantFP::get(*Context, APFloat(APInt(64, 0x4330000000000000ULL))));
|
||||
ConstantFP::get(*Context, APFloat(APFloat::IEEEdouble,
|
||||
APInt(64, 0x4330000000000000ULL))));
|
||||
CV1.push_back(
|
||||
ConstantFP::get(*Context, APFloat(APInt(64, 0x4530000000000000ULL))));
|
||||
ConstantFP::get(*Context, APFloat(APFloat::IEEEdouble,
|
||||
APInt(64, 0x4530000000000000ULL))));
|
||||
Constant *C1 = ConstantVector::get(CV1);
|
||||
SDValue CPIdx1 = DAG.getConstantPool(C1, getPointerTy(), 16);
|
||||
|
||||
@ -8565,9 +8567,11 @@ SDValue X86TargetLowering::LowerFABS(SDValue Op, SelectionDAG &DAG) const {
|
||||
}
|
||||
Constant *C;
|
||||
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
|
||||
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);
|
||||
SDValue CPIdx = DAG.getConstantPool(C, getPointerTy());
|
||||
unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment();
|
||||
@ -8597,9 +8601,11 @@ SDValue X86TargetLowering::LowerFNEG(SDValue Op, SelectionDAG &DAG) const {
|
||||
}
|
||||
Constant *C;
|
||||
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
|
||||
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);
|
||||
SDValue CPIdx = DAG.getConstantPool(C, getPointerTy());
|
||||
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.
|
||||
SmallVector<Constant*,4> CV;
|
||||
if (SrcVT == MVT::f64) {
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(64, 1ULL << 63))));
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(64, 0))));
|
||||
const fltSemantics &Sem = APFloat::IEEEdouble;
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(Sem, APInt(64, 1ULL << 63))));
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(Sem, APInt(64, 0))));
|
||||
} else {
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, 1U << 31))));
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, 0))));
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, 0))));
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, 0))));
|
||||
const fltSemantics &Sem = APFloat::IEEEsingle;
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(Sem, APInt(32, 1U << 31))));
|
||||
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))));
|
||||
}
|
||||
Constant *C = ConstantVector::get(CV);
|
||||
SDValue CPIdx = DAG.getConstantPool(C, getPointerTy(), 16);
|
||||
@ -8672,13 +8680,17 @@ SDValue X86TargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const {
|
||||
// Clear first operand sign bit.
|
||||
CV.clear();
|
||||
if (VT == MVT::f64) {
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(64, ~(1ULL << 63)))));
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(64, 0))));
|
||||
const fltSemantics &Sem = APFloat::IEEEdouble;
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(Sem,
|
||||
APInt(64, ~(1ULL << 63)))));
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(Sem, APInt(64, 0))));
|
||||
} else {
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, ~(1U << 31)))));
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, 0))));
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, 0))));
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(APInt(32, 0))));
|
||||
const fltSemantics &Sem = APFloat::IEEEsingle;
|
||||
CV.push_back(ConstantFP::get(*Context, APFloat(Sem,
|
||||
APInt(32, ~(1U << 31)))));
|
||||
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);
|
||||
CPIdx = DAG.getConstantPool(C, getPointerTy(), 16);
|
||||
|
Loading…
Reference in New Issue
Block a user