mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-13 09:33:50 +00:00
In various places throughout the code generator, there were special
checks to avoid performing compile-time arithmetic on PPCDoubleDouble. Now that APFloat supports arithmetic on PPCDoubleDouble, those checks are no longer needed, and we can treat the type like any other. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166958 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
159c735f7b
commit
e669c930a6
@ -1199,9 +1199,6 @@ public:
|
||||
/// have to duplicate its logic everywhere it's called.
|
||||
bool isExactlyValue(double V) const {
|
||||
bool ignored;
|
||||
// convert is not supported on this type
|
||||
if (&Value->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble)
|
||||
return false;
|
||||
APFloat Tmp(V);
|
||||
Tmp.convert(Value->getValueAPF().getSemantics(),
|
||||
APFloat::rmNearestTiesToEven, &ignored);
|
||||
|
@ -282,9 +282,6 @@ public:
|
||||
|
||||
bool isExactlyValue(double V) const {
|
||||
bool ignored;
|
||||
// convert is not supported on this type
|
||||
if (&Val.getSemantics() == &APFloat::PPCDoubleDouble)
|
||||
return false;
|
||||
APFloat FV(V);
|
||||
FV.convert(Val.getSemantics(), APFloat::rmNearestTiesToEven, &ignored);
|
||||
return isExactlyValue(FV);
|
||||
|
@ -393,10 +393,6 @@ static char isNegatibleForFree(SDValue Op, bool LegalOperations,
|
||||
const TargetLowering &TLI,
|
||||
const TargetOptions *Options,
|
||||
unsigned Depth = 0) {
|
||||
// No compile time optimizations on this type.
|
||||
if (Op.getValueType() == MVT::ppcf128)
|
||||
return 0;
|
||||
|
||||
// fneg is removable even if it has multiple uses.
|
||||
if (Op.getOpcode() == ISD::FNEG) return 2;
|
||||
|
||||
@ -5705,7 +5701,7 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
|
||||
}
|
||||
|
||||
// fold (fadd c1, c2) -> c1 + c2
|
||||
if (N0CFP && N1CFP && VT != MVT::ppcf128)
|
||||
if (N0CFP && N1CFP)
|
||||
return DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, N0, N1);
|
||||
// canonicalize constant to RHS
|
||||
if (N0CFP && !N1CFP)
|
||||
@ -5892,7 +5888,7 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
|
||||
}
|
||||
|
||||
// fold (fsub c1, c2) -> c1-c2
|
||||
if (N0CFP && N1CFP && VT != MVT::ppcf128)
|
||||
if (N0CFP && N1CFP)
|
||||
return DAG.getNode(ISD::FSUB, N->getDebugLoc(), VT, N0, N1);
|
||||
// fold (fsub A, 0) -> A
|
||||
if (DAG.getTarget().Options.UnsafeFPMath &&
|
||||
@ -5984,7 +5980,7 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) {
|
||||
}
|
||||
|
||||
// fold (fmul c1, c2) -> c1*c2
|
||||
if (N0CFP && N1CFP && VT != MVT::ppcf128)
|
||||
if (N0CFP && N1CFP)
|
||||
return DAG.getNode(ISD::FMUL, N->getDebugLoc(), VT, N0, N1);
|
||||
// canonicalize constant to RHS
|
||||
if (N0CFP && !N1CFP)
|
||||
@ -6121,11 +6117,11 @@ SDValue DAGCombiner::visitFDIV(SDNode *N) {
|
||||
}
|
||||
|
||||
// fold (fdiv c1, c2) -> c1/c2
|
||||
if (N0CFP && N1CFP && VT != MVT::ppcf128)
|
||||
if (N0CFP && N1CFP)
|
||||
return DAG.getNode(ISD::FDIV, N->getDebugLoc(), VT, N0, N1);
|
||||
|
||||
// fold (fdiv X, c2) -> fmul X, 1/c2 if losing precision is acceptable.
|
||||
if (N1CFP && VT != MVT::ppcf128 && DAG.getTarget().Options.UnsafeFPMath) {
|
||||
if (N1CFP && DAG.getTarget().Options.UnsafeFPMath) {
|
||||
// Compute the reciprocal 1.0 / c2.
|
||||
APFloat N1APF = N1CFP->getValueAPF();
|
||||
APFloat Recip(N1APF.getSemantics(), 1); // 1.0
|
||||
@ -6168,7 +6164,7 @@ SDValue DAGCombiner::visitFREM(SDNode *N) {
|
||||
EVT VT = N->getValueType(0);
|
||||
|
||||
// fold (frem c1, c2) -> fmod(c1,c2)
|
||||
if (N0CFP && N1CFP && VT != MVT::ppcf128)
|
||||
if (N0CFP && N1CFP)
|
||||
return DAG.getNode(ISD::FREM, N->getDebugLoc(), VT, N0, N1);
|
||||
|
||||
return SDValue();
|
||||
@ -6181,7 +6177,7 @@ SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) {
|
||||
ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1);
|
||||
EVT VT = N->getValueType(0);
|
||||
|
||||
if (N0CFP && N1CFP && VT != MVT::ppcf128) // Constant fold
|
||||
if (N0CFP && N1CFP) // Constant fold
|
||||
return DAG.getNode(ISD::FCOPYSIGN, N->getDebugLoc(), VT, N0, N1);
|
||||
|
||||
if (N1CFP) {
|
||||
@ -6231,7 +6227,7 @@ SDValue DAGCombiner::visitSINT_TO_FP(SDNode *N) {
|
||||
EVT OpVT = N0.getValueType();
|
||||
|
||||
// fold (sint_to_fp c1) -> c1fp
|
||||
if (N0C && OpVT != MVT::ppcf128 &&
|
||||
if (N0C &&
|
||||
// ...but only if the target supports immediate floating-point values
|
||||
(!LegalOperations ||
|
||||
TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT)))
|
||||
@ -6288,7 +6284,7 @@ SDValue DAGCombiner::visitUINT_TO_FP(SDNode *N) {
|
||||
EVT OpVT = N0.getValueType();
|
||||
|
||||
// fold (uint_to_fp c1) -> c1fp
|
||||
if (N0C && OpVT != MVT::ppcf128 &&
|
||||
if (N0C &&
|
||||
// ...but only if the target supports immediate floating-point values
|
||||
(!LegalOperations ||
|
||||
TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT)))
|
||||
@ -6343,7 +6339,7 @@ SDValue DAGCombiner::visitFP_TO_UINT(SDNode *N) {
|
||||
EVT VT = N->getValueType(0);
|
||||
|
||||
// fold (fp_to_uint c1fp) -> c1
|
||||
if (N0CFP && VT != MVT::ppcf128)
|
||||
if (N0CFP)
|
||||
return DAG.getNode(ISD::FP_TO_UINT, N->getDebugLoc(), VT, N0);
|
||||
|
||||
return SDValue();
|
||||
@ -6356,7 +6352,7 @@ SDValue DAGCombiner::visitFP_ROUND(SDNode *N) {
|
||||
EVT VT = N->getValueType(0);
|
||||
|
||||
// fold (fp_round c1fp) -> c1fp
|
||||
if (N0CFP && N0.getValueType() != MVT::ppcf128)
|
||||
if (N0CFP)
|
||||
return DAG.getNode(ISD::FP_ROUND, N->getDebugLoc(), VT, N0, N1);
|
||||
|
||||
// fold (fp_round (fp_extend x)) -> x
|
||||
@ -6410,7 +6406,7 @@ SDValue DAGCombiner::visitFP_EXTEND(SDNode *N) {
|
||||
return SDValue();
|
||||
|
||||
// fold (fp_extend c1fp) -> c1fp
|
||||
if (N0CFP && VT != MVT::ppcf128)
|
||||
if (N0CFP)
|
||||
return DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), VT, N0);
|
||||
|
||||
// Turn fp_extend(fp_round(X, 1)) -> x since the fp_round doesn't affect the
|
||||
@ -6497,7 +6493,7 @@ SDValue DAGCombiner::visitFCEIL(SDNode *N) {
|
||||
EVT VT = N->getValueType(0);
|
||||
|
||||
// fold (fceil c1) -> fceil(c1)
|
||||
if (N0CFP && VT != MVT::ppcf128)
|
||||
if (N0CFP)
|
||||
return DAG.getNode(ISD::FCEIL, N->getDebugLoc(), VT, N0);
|
||||
|
||||
return SDValue();
|
||||
@ -6509,7 +6505,7 @@ SDValue DAGCombiner::visitFTRUNC(SDNode *N) {
|
||||
EVT VT = N->getValueType(0);
|
||||
|
||||
// fold (ftrunc c1) -> ftrunc(c1)
|
||||
if (N0CFP && VT != MVT::ppcf128)
|
||||
if (N0CFP)
|
||||
return DAG.getNode(ISD::FTRUNC, N->getDebugLoc(), VT, N0);
|
||||
|
||||
return SDValue();
|
||||
@ -6521,7 +6517,7 @@ SDValue DAGCombiner::visitFFLOOR(SDNode *N) {
|
||||
EVT VT = N->getValueType(0);
|
||||
|
||||
// fold (ffloor c1) -> ffloor(c1)
|
||||
if (N0CFP && VT != MVT::ppcf128)
|
||||
if (N0CFP)
|
||||
return DAG.getNode(ISD::FFLOOR, N->getDebugLoc(), VT, N0);
|
||||
|
||||
return SDValue();
|
||||
@ -6538,7 +6534,7 @@ SDValue DAGCombiner::visitFABS(SDNode *N) {
|
||||
}
|
||||
|
||||
// fold (fabs c1) -> fabs(c1)
|
||||
if (N0CFP && VT != MVT::ppcf128)
|
||||
if (N0CFP)
|
||||
return DAG.getNode(ISD::FABS, N->getDebugLoc(), VT, N0);
|
||||
// fold (fabs (fabs x)) -> (fabs x)
|
||||
if (N0.getOpcode() == ISD::FABS)
|
||||
|
@ -91,11 +91,6 @@ bool ConstantFPSDNode::isValueValidForType(EVT VT,
|
||||
const APFloat& Val) {
|
||||
assert(VT.isFloatingPoint() && "Can only convert between FP types");
|
||||
|
||||
// PPC long double cannot be converted to any other type.
|
||||
if (VT == MVT::ppcf128 ||
|
||||
&Val.getSemantics() == &APFloat::PPCDoubleDouble)
|
||||
return false;
|
||||
|
||||
// convert modifies in place, so make a copy.
|
||||
APFloat Val2 = APFloat(Val);
|
||||
bool losesInfo;
|
||||
@ -1612,10 +1607,6 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1,
|
||||
}
|
||||
if (ConstantFPSDNode *N1C = dyn_cast<ConstantFPSDNode>(N1.getNode())) {
|
||||
if (ConstantFPSDNode *N2C = dyn_cast<ConstantFPSDNode>(N2.getNode())) {
|
||||
// No compile time operations on this type yet.
|
||||
if (N1C->getValueType(0) == MVT::ppcf128)
|
||||
return SDValue();
|
||||
|
||||
APFloat::cmpResult R = N1C->getValueAPF().compare(N2C->getValueAPF());
|
||||
switch (Cond) {
|
||||
default: break;
|
||||
@ -2447,8 +2438,6 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL,
|
||||
return getConstant(Val.zextOrTrunc(VT.getSizeInBits()), VT);
|
||||
case ISD::UINT_TO_FP:
|
||||
case ISD::SINT_TO_FP: {
|
||||
// No compile time operations on ppcf128.
|
||||
if (VT == MVT::ppcf128) break;
|
||||
APFloat apf(APInt::getNullValue(VT.getSizeInBits()));
|
||||
(void)apf.convertFromAPInt(Val,
|
||||
Opcode==ISD::SINT_TO_FP,
|
||||
@ -2477,61 +2466,59 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL,
|
||||
// Constant fold unary operations with a floating point constant operand.
|
||||
if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Operand.getNode())) {
|
||||
APFloat V = C->getValueAPF(); // make copy
|
||||
if (VT != MVT::ppcf128 && Operand.getValueType() != MVT::ppcf128) {
|
||||
switch (Opcode) {
|
||||
case ISD::FNEG:
|
||||
V.changeSign();
|
||||
switch (Opcode) {
|
||||
case ISD::FNEG:
|
||||
V.changeSign();
|
||||
return getConstantFP(V, VT);
|
||||
case ISD::FABS:
|
||||
V.clearSign();
|
||||
return getConstantFP(V, VT);
|
||||
case ISD::FCEIL: {
|
||||
APFloat::opStatus fs = V.roundToIntegral(APFloat::rmTowardPositive);
|
||||
if (fs == APFloat::opOK || fs == APFloat::opInexact)
|
||||
return getConstantFP(V, VT);
|
||||
case ISD::FABS:
|
||||
V.clearSign();
|
||||
break;
|
||||
}
|
||||
case ISD::FTRUNC: {
|
||||
APFloat::opStatus fs = V.roundToIntegral(APFloat::rmTowardZero);
|
||||
if (fs == APFloat::opOK || fs == APFloat::opInexact)
|
||||
return getConstantFP(V, VT);
|
||||
case ISD::FCEIL: {
|
||||
APFloat::opStatus fs = V.roundToIntegral(APFloat::rmTowardPositive);
|
||||
if (fs == APFloat::opOK || fs == APFloat::opInexact)
|
||||
return getConstantFP(V, VT);
|
||||
break;
|
||||
}
|
||||
case ISD::FTRUNC: {
|
||||
APFloat::opStatus fs = V.roundToIntegral(APFloat::rmTowardZero);
|
||||
if (fs == APFloat::opOK || fs == APFloat::opInexact)
|
||||
return getConstantFP(V, VT);
|
||||
break;
|
||||
}
|
||||
case ISD::FFLOOR: {
|
||||
APFloat::opStatus fs = V.roundToIntegral(APFloat::rmTowardNegative);
|
||||
if (fs == APFloat::opOK || fs == APFloat::opInexact)
|
||||
return getConstantFP(V, VT);
|
||||
break;
|
||||
}
|
||||
case ISD::FP_EXTEND: {
|
||||
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),
|
||||
APFloat::rmNearestTiesToEven, &ignored);
|
||||
break;
|
||||
}
|
||||
case ISD::FFLOOR: {
|
||||
APFloat::opStatus fs = V.roundToIntegral(APFloat::rmTowardNegative);
|
||||
if (fs == APFloat::opOK || fs == APFloat::opInexact)
|
||||
return getConstantFP(V, VT);
|
||||
}
|
||||
case ISD::FP_TO_SINT:
|
||||
case ISD::FP_TO_UINT: {
|
||||
integerPart x[2];
|
||||
bool ignored;
|
||||
assert(integerPartWidth >= 64);
|
||||
// FIXME need to be more flexible about rounding mode.
|
||||
APFloat::opStatus s = V.convertToInteger(x, VT.getSizeInBits(),
|
||||
Opcode==ISD::FP_TO_SINT,
|
||||
APFloat::rmTowardZero, &ignored);
|
||||
if (s==APFloat::opInvalidOp) // inexact is OK, in fact usual
|
||||
break;
|
||||
APInt api(VT.getSizeInBits(), x);
|
||||
return getConstant(api, VT);
|
||||
}
|
||||
case ISD::BITCAST:
|
||||
if (VT == MVT::i32 && C->getValueType(0) == MVT::f32)
|
||||
return getConstant((uint32_t)V.bitcastToAPInt().getZExtValue(), VT);
|
||||
else if (VT == MVT::i64 && C->getValueType(0) == MVT::f64)
|
||||
return getConstant(V.bitcastToAPInt().getZExtValue(), VT);
|
||||
break;
|
||||
}
|
||||
case ISD::FP_EXTEND: {
|
||||
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),
|
||||
APFloat::rmNearestTiesToEven, &ignored);
|
||||
return getConstantFP(V, VT);
|
||||
}
|
||||
case ISD::FP_TO_SINT:
|
||||
case ISD::FP_TO_UINT: {
|
||||
integerPart x[2];
|
||||
bool ignored;
|
||||
assert(integerPartWidth >= 64);
|
||||
// FIXME need to be more flexible about rounding mode.
|
||||
APFloat::opStatus s = V.convertToInteger(x, VT.getSizeInBits(),
|
||||
Opcode==ISD::FP_TO_SINT,
|
||||
APFloat::rmTowardZero, &ignored);
|
||||
if (s==APFloat::opInvalidOp) // inexact is OK, in fact usual
|
||||
break;
|
||||
}
|
||||
APInt api(VT.getSizeInBits(), x);
|
||||
return getConstant(api, VT);
|
||||
}
|
||||
case ISD::BITCAST:
|
||||
if (VT == MVT::i32 && C->getValueType(0) == MVT::f32)
|
||||
return getConstant((uint32_t)V.bitcastToAPInt().getZExtValue(), VT);
|
||||
else if (VT == MVT::i64 && C->getValueType(0) == MVT::f64)
|
||||
return getConstant(V.bitcastToAPInt().getZExtValue(), VT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3052,7 +3039,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT,
|
||||
// Cannonicalize constant to RHS if commutative
|
||||
std::swap(N1CFP, N2CFP);
|
||||
std::swap(N1, N2);
|
||||
} else if (N2CFP && VT != MVT::ppcf128) {
|
||||
} else if (N2CFP) {
|
||||
APFloat V1 = N1CFP->getValueAPF(), V2 = N2CFP->getValueAPF();
|
||||
APFloat::opStatus s;
|
||||
switch (Opcode) {
|
||||
|
@ -220,8 +220,6 @@ static Instruction *getInsertPointForUses(Instruction *User, Value *Def,
|
||||
/// ConvertToSInt - Convert APF to an integer, if possible.
|
||||
static bool ConvertToSInt(const APFloat &APF, int64_t &IntVal) {
|
||||
bool isExact = false;
|
||||
if (&APF.getSemantics() == &APFloat::PPCDoubleDouble)
|
||||
return false;
|
||||
// See if we can convert this to an int64_t
|
||||
uint64_t UIntVal;
|
||||
if (APF.convertToInteger(&UIntVal, 64, true, APFloat::rmTowardZero,
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc < %s -march=ppc64 | grep __floatditf
|
||||
; RUN: llc < %s -march=ppc64 | FileCheck %s
|
||||
; CHECK-NOT: __floatditf
|
||||
|
||||
define i64 @__fixunstfdi(ppc_fp128 %a) nounwind {
|
||||
entry:
|
||||
|
Loading…
x
Reference in New Issue
Block a user