forked from OSchip/llvm-project
[LegalizeTypes] Remove code for softening a float type to itself.
This was previously used to turn fp128 operations into libcalls on X86. This is now done through op legalization after r371672. This restores much of this code to before r254653. llvm-svn: 371709
This commit is contained in:
parent
e8b2b8868d
commit
b8dd075275
|
@ -123,8 +123,7 @@ public:
|
|||
TypeLegal, // The target natively supports this type.
|
||||
TypePromoteInteger, // Replace this integer with a larger one.
|
||||
TypeExpandInteger, // Split this integer into two of half the size.
|
||||
TypeSoftenFloat, // Convert this float to a same size integer type,
|
||||
// if an operation is not supported in target HW.
|
||||
TypeSoftenFloat, // Convert this float to a same size integer type.
|
||||
TypeExpandFloat, // Split this float into two of half the size.
|
||||
TypeScalarizeVector, // Replace this one-element vector with its element.
|
||||
TypeSplitVector, // Split this vector into two of half the size.
|
||||
|
@ -2768,7 +2767,6 @@ private:
|
|||
/// up the MVT::LAST_VALUETYPE value to the next multiple of 8.
|
||||
uint32_t CondCodeActions[ISD::SETCC_INVALID][(MVT::LAST_VALUETYPE + 7) / 8];
|
||||
|
||||
protected:
|
||||
ValueTypeActionImpl ValueTypeActions;
|
||||
|
||||
private:
|
||||
|
|
|
@ -968,15 +968,13 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
|
|||
|
||||
#ifndef NDEBUG
|
||||
for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i)
|
||||
assert((TLI.getTypeAction(*DAG.getContext(), Node->getValueType(i)) ==
|
||||
TargetLowering::TypeLegal ||
|
||||
TLI.isTypeLegal(Node->getValueType(i))) &&
|
||||
assert(TLI.getTypeAction(*DAG.getContext(), Node->getValueType(i)) ==
|
||||
TargetLowering::TypeLegal &&
|
||||
"Unexpected illegal type!");
|
||||
|
||||
for (const SDValue &Op : Node->op_values())
|
||||
assert((TLI.getTypeAction(*DAG.getContext(), Op.getValueType()) ==
|
||||
TargetLowering::TypeLegal ||
|
||||
TLI.isTypeLegal(Op.getValueType()) ||
|
||||
Op.getOpcode() == ISD::TargetConstant ||
|
||||
Op.getOpcode() == ISD::Register) &&
|
||||
"Unexpected illegal type!");
|
||||
|
|
|
@ -42,10 +42,10 @@ static RTLIB::Libcall GetFPLibCall(EVT VT,
|
|||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Convert Float Results to Integer for Non-HW-supported Operations.
|
||||
// Convert Float Results to Integer
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
|
||||
void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
|
||||
LLVM_DEBUG(dbgs() << "Soften float result " << ResNo << ": "; N->dump(&DAG);
|
||||
dbgs() << "\n");
|
||||
SDValue R = SDValue();
|
||||
|
@ -58,26 +58,18 @@ bool DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
|
|||
#endif
|
||||
llvm_unreachable("Do not know how to soften the result of this operator!");
|
||||
|
||||
case ISD::Register:
|
||||
case ISD::CopyFromReg:
|
||||
case ISD::CopyToReg:
|
||||
assert(isLegalInHWReg(N->getValueType(ResNo)) &&
|
||||
"Unsupported SoftenFloatRes opcode!");
|
||||
// Only when isLegalInHWReg, we can skip check of the operands.
|
||||
R = SDValue(N, ResNo);
|
||||
break;
|
||||
case ISD::MERGE_VALUES:R = SoftenFloatRes_MERGE_VALUES(N, ResNo); break;
|
||||
case ISD::BITCAST: R = SoftenFloatRes_BITCAST(N, ResNo); break;
|
||||
case ISD::BITCAST: R = SoftenFloatRes_BITCAST(N); break;
|
||||
case ISD::BUILD_PAIR: R = SoftenFloatRes_BUILD_PAIR(N); break;
|
||||
case ISD::ConstantFP: R = SoftenFloatRes_ConstantFP(N, ResNo); break;
|
||||
case ISD::ConstantFP: R = SoftenFloatRes_ConstantFP(N); break;
|
||||
case ISD::EXTRACT_VECTOR_ELT:
|
||||
R = SoftenFloatRes_EXTRACT_VECTOR_ELT(N, ResNo); break;
|
||||
case ISD::FABS: R = SoftenFloatRes_FABS(N, ResNo); break;
|
||||
case ISD::FABS: R = SoftenFloatRes_FABS(N); break;
|
||||
case ISD::FMINNUM: R = SoftenFloatRes_FMINNUM(N); break;
|
||||
case ISD::FMAXNUM: R = SoftenFloatRes_FMAXNUM(N); break;
|
||||
case ISD::FADD: R = SoftenFloatRes_FADD(N); break;
|
||||
case ISD::FCEIL: R = SoftenFloatRes_FCEIL(N); break;
|
||||
case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N, ResNo); break;
|
||||
case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break;
|
||||
case ISD::FCOS: R = SoftenFloatRes_FCOS(N); break;
|
||||
case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break;
|
||||
case ISD::FEXP: R = SoftenFloatRes_FEXP(N); break;
|
||||
|
@ -89,7 +81,7 @@ bool DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
|
|||
case ISD::FMA: R = SoftenFloatRes_FMA(N); break;
|
||||
case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break;
|
||||
case ISD::FNEARBYINT: R = SoftenFloatRes_FNEARBYINT(N); break;
|
||||
case ISD::FNEG: R = SoftenFloatRes_FNEG(N, ResNo); break;
|
||||
case ISD::FNEG: R = SoftenFloatRes_FNEG(N); break;
|
||||
case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break;
|
||||
case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break;
|
||||
case ISD::FP16_TO_FP: R = SoftenFloatRes_FP16_TO_FP(N); break;
|
||||
|
@ -102,30 +94,24 @@ bool DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
|
|||
case ISD::FSQRT: R = SoftenFloatRes_FSQRT(N); break;
|
||||
case ISD::FSUB: R = SoftenFloatRes_FSUB(N); break;
|
||||
case ISD::FTRUNC: R = SoftenFloatRes_FTRUNC(N); break;
|
||||
case ISD::LOAD: R = SoftenFloatRes_LOAD(N, ResNo); break;
|
||||
case ISD::LOAD: R = SoftenFloatRes_LOAD(N); break;
|
||||
case ISD::ATOMIC_SWAP: R = BitcastToInt_ATOMIC_SWAP(N); break;
|
||||
case ISD::SELECT: R = SoftenFloatRes_SELECT(N, ResNo); break;
|
||||
case ISD::SELECT_CC: R = SoftenFloatRes_SELECT_CC(N, ResNo); break;
|
||||
case ISD::SELECT: R = SoftenFloatRes_SELECT(N); break;
|
||||
case ISD::SELECT_CC: R = SoftenFloatRes_SELECT_CC(N); break;
|
||||
case ISD::SINT_TO_FP:
|
||||
case ISD::UINT_TO_FP: R = SoftenFloatRes_XINT_TO_FP(N); break;
|
||||
case ISD::UNDEF: R = SoftenFloatRes_UNDEF(N); break;
|
||||
case ISD::VAARG: R = SoftenFloatRes_VAARG(N); break;
|
||||
}
|
||||
|
||||
if (R.getNode() && R.getNode() != N) {
|
||||
// If R is null, the sub-method took care of registering the result.
|
||||
if (R.getNode()) {
|
||||
assert(R.getNode() != N);
|
||||
SetSoftenedFloat(SDValue(N, ResNo), R);
|
||||
// Return true only if the node is changed, assuming that the operands
|
||||
// are also converted when necessary.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, return false to tell caller to scan operands.
|
||||
return false;
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_BITCAST(SDNode *N, unsigned ResNo) {
|
||||
if (isLegalInHWReg(N->getValueType(ResNo)))
|
||||
return SDValue(N, ResNo);
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_BITCAST(SDNode *N) {
|
||||
return BitConvertToInteger(N->getOperand(0));
|
||||
}
|
||||
|
||||
|
@ -144,10 +130,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) {
|
|||
BitConvertToInteger(N->getOperand(1)));
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(SDNode *N, unsigned ResNo) {
|
||||
// When LegalInHWReg, we can load better from the constant pool.
|
||||
if (isLegalInHWReg(N->getValueType(ResNo)))
|
||||
return SDValue(N, ResNo);
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(SDNode *N) {
|
||||
ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N);
|
||||
// In ppcf128, the high 64 bits are always first in memory regardless
|
||||
// of Endianness. LLVM's APFloat representation is not Endian sensitive,
|
||||
|
@ -172,19 +155,13 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(SDNode *N, unsigned ResNo) {
|
|||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N, unsigned ResNo) {
|
||||
// When LegalInHWReg, keep the extracted value in register.
|
||||
if (isLegalInHWReg(N->getValueType(ResNo)))
|
||||
return SDValue(N, ResNo);
|
||||
SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0));
|
||||
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N),
|
||||
NewOp.getValueType().getVectorElementType(),
|
||||
NewOp, N->getOperand(1));
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N, unsigned ResNo) {
|
||||
// When LegalInHWReg, FABS can be implemented as native bitwise operations.
|
||||
if (isLegalInHWReg(N->getValueType(ResNo)))
|
||||
return SDValue(N, ResNo);
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N) {
|
||||
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
||||
unsigned Size = NVT.getSizeInBits();
|
||||
|
||||
|
@ -262,10 +239,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) {
|
|||
NVT, Op, CallOptions, SDLoc(N)).first;
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N, unsigned ResNo) {
|
||||
// When LegalInHWReg, FCOPYSIGN can be implemented as native bitwise operations.
|
||||
if (isLegalInHWReg(N->getValueType(ResNo)))
|
||||
return SDValue(N, ResNo);
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) {
|
||||
SDValue LHS = GetSoftenedFloat(N->getOperand(0));
|
||||
SDValue RHS = BitConvertToInteger(N->getOperand(1));
|
||||
SDLoc dl(N);
|
||||
|
@ -486,14 +460,11 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) {
|
|||
NVT, Op, CallOptions, SDLoc(N)).first;
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N, unsigned ResNo) {
|
||||
// When LegalInHWReg, FNEG can be implemented as native bitwise operations.
|
||||
if (isLegalInHWReg(N->getValueType(ResNo)))
|
||||
return SDValue(N, ResNo);
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) {
|
||||
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
||||
SDLoc dl(N);
|
||||
|
||||
EVT FloatVT = N->getValueType(ResNo);
|
||||
EVT FloatVT = N->getValueType(0);
|
||||
if (FloatVT == MVT::f32 || FloatVT == MVT::f64 || FloatVT == MVT::f128) {
|
||||
// Expand Y = FNEG(X) -> Y = X ^ sign mask
|
||||
APInt SignMask = APInt::getSignMask(NVT.getSizeInBits());
|
||||
|
@ -727,8 +698,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) {
|
|||
NVT, Op, CallOptions, SDLoc(N)).first;
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N, unsigned ResNo) {
|
||||
bool LegalInHWReg = isLegalInHWReg(N->getValueType(ResNo));
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) {
|
||||
LoadSDNode *L = cast<LoadSDNode>(N);
|
||||
EVT VT = N->getValueType(0);
|
||||
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
|
||||
|
@ -759,23 +729,17 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N, unsigned ResNo) {
|
|||
// use the new one.
|
||||
ReplaceValueWith(SDValue(N, 1), NewL.getValue(1));
|
||||
auto ExtendNode = DAG.getNode(ISD::FP_EXTEND, dl, VT, NewL);
|
||||
if (LegalInHWReg)
|
||||
return ExtendNode;
|
||||
return BitConvertToInteger(ExtendNode);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N, unsigned ResNo) {
|
||||
if (isLegalInHWReg(N->getValueType(ResNo)))
|
||||
return SDValue(N, ResNo);
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N) {
|
||||
SDValue LHS = GetSoftenedFloat(N->getOperand(1));
|
||||
SDValue RHS = GetSoftenedFloat(N->getOperand(2));
|
||||
return DAG.getSelect(SDLoc(N),
|
||||
LHS.getValueType(), N->getOperand(0), LHS, RHS);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N, unsigned ResNo) {
|
||||
if (isLegalInHWReg(N->getValueType(ResNo)))
|
||||
return SDValue(N, ResNo);
|
||||
SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N) {
|
||||
SDValue LHS = GetSoftenedFloat(N->getOperand(2));
|
||||
SDValue RHS = GetSoftenedFloat(N->getOperand(3));
|
||||
return DAG.getNode(ISD::SELECT_CC, SDLoc(N),
|
||||
|
@ -840,7 +804,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) {
|
|||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Convert Float Operand to Integer for Non-HW-supported Operations.
|
||||
// Convert Float Operand to Integer
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
|
||||
|
@ -850,8 +814,6 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
|
|||
|
||||
switch (N->getOpcode()) {
|
||||
default:
|
||||
if (CanSkipSoftenFloatOperand(N, OpNo))
|
||||
return false;
|
||||
#ifndef NDEBUG
|
||||
dbgs() << "SoftenFloatOperand Op #" << OpNo << ": ";
|
||||
N->dump(&DAG); dbgs() << "\n";
|
||||
|
@ -859,11 +821,7 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
|
|||
llvm_unreachable("Do not know how to soften this operator's operand!");
|
||||
|
||||
case ISD::BITCAST: Res = SoftenFloatOp_BITCAST(N); break;
|
||||
case ISD::CopyToReg: Res = SoftenFloatOp_COPY_TO_REG(N); break;
|
||||
case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(N); break;
|
||||
case ISD::FABS: Res = SoftenFloatOp_FABS(N); break;
|
||||
case ISD::FCOPYSIGN: Res = SoftenFloatOp_FCOPYSIGN(N); break;
|
||||
case ISD::FNEG: Res = SoftenFloatOp_FNEG(N); break;
|
||||
case ISD::FP_EXTEND: Res = SoftenFloatOp_FP_EXTEND(N); break;
|
||||
case ISD::FP_TO_FP16: // Same as FP_ROUND for softening purposes
|
||||
case ISD::FP_ROUND: Res = SoftenFloatOp_FP_ROUND(N); break;
|
||||
|
@ -873,19 +831,9 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
|
|||
case ISD::LLROUND: Res = SoftenFloatOp_LLROUND(N); break;
|
||||
case ISD::LRINT: Res = SoftenFloatOp_LRINT(N); break;
|
||||
case ISD::LLRINT: Res = SoftenFloatOp_LLRINT(N); break;
|
||||
case ISD::SELECT: Res = SoftenFloatOp_SELECT(N); break;
|
||||
case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N, OpNo); break;
|
||||
case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break;
|
||||
case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break;
|
||||
case ISD::STORE:
|
||||
Res = SoftenFloatOp_STORE(N, OpNo);
|
||||
// Do not try to analyze or soften this node again if the value is
|
||||
// or can be held in a register. In that case, Res.getNode() should
|
||||
// be equal to N.
|
||||
if (Res.getNode() == N &&
|
||||
isLegalInHWReg(N->getOperand(OpNo).getValueType()))
|
||||
return false;
|
||||
// Otherwise, we need to reanalyze and lower the new Res nodes.
|
||||
break;
|
||||
case ISD::STORE: Res = SoftenFloatOp_STORE(N, OpNo); break;
|
||||
}
|
||||
|
||||
// If the result is null, the sub-method took care of registering results etc.
|
||||
|
@ -897,66 +845,18 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
|
|||
return true;
|
||||
|
||||
assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
|
||||
"Invalid operand expansion");
|
||||
"Invalid operand promotion");
|
||||
|
||||
ReplaceValueWith(SDValue(N, 0), Res);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DAGTypeLegalizer::CanSkipSoftenFloatOperand(SDNode *N, unsigned OpNo) {
|
||||
if (!isLegalInHWReg(N->getOperand(OpNo).getValueType()))
|
||||
return false;
|
||||
|
||||
// When the operand type can be kept in registers there is nothing to do for
|
||||
// the following opcodes.
|
||||
switch (N->getOperand(OpNo).getOpcode()) {
|
||||
case ISD::BITCAST:
|
||||
case ISD::ConstantFP:
|
||||
case ISD::CopyFromReg:
|
||||
case ISD::CopyToReg:
|
||||
case ISD::FABS:
|
||||
case ISD::FCOPYSIGN:
|
||||
case ISD::FNEG:
|
||||
case ISD::Register:
|
||||
case ISD::SELECT:
|
||||
case ISD::SELECT_CC:
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (N->getOpcode()) {
|
||||
case ISD::ConstantFP: // Leaf node.
|
||||
case ISD::CopyFromReg: // Operand is a register that we know to be left
|
||||
// unchanged by SoftenFloatResult().
|
||||
case ISD::Register: // Leaf node.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_BITCAST(SDNode *N) {
|
||||
SDValue Op0 = GetSoftenedFloat(N->getOperand(0));
|
||||
|
||||
if (Op0 == N->getOperand(0))
|
||||
return SDValue();
|
||||
|
||||
return DAG.getNode(ISD::BITCAST, SDLoc(N), N->getValueType(0), Op0);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_COPY_TO_REG(SDNode *N) {
|
||||
SDValue Op1 = GetSoftenedFloat(N->getOperand(1));
|
||||
SDValue Op2 = GetSoftenedFloat(N->getOperand(2));
|
||||
|
||||
if (Op1 == N->getOperand(1) && Op2 == N->getOperand(2))
|
||||
return SDValue();
|
||||
|
||||
if (N->getNumOperands() == 3)
|
||||
return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Op1, Op2), 0);
|
||||
|
||||
return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Op1, Op2,
|
||||
N->getOperand(3)),
|
||||
0);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_FP_EXTEND(SDNode *N) {
|
||||
// If we get here, the result must be legal but the source illegal.
|
||||
EVT SVT = N->getOperand(0).getValueType();
|
||||
|
@ -1019,34 +919,6 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) {
|
|||
0);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_FABS(SDNode *N) {
|
||||
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
||||
|
||||
if (Op == N->getOperand(0))
|
||||
return SDValue();
|
||||
|
||||
return SDValue(DAG.UpdateNodeOperands(N, Op), 0);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_FCOPYSIGN(SDNode *N) {
|
||||
SDValue Op0 = GetSoftenedFloat(N->getOperand(0));
|
||||
SDValue Op1 = GetSoftenedFloat(N->getOperand(1));
|
||||
|
||||
if (Op0 == N->getOperand(0) && Op1 == N->getOperand(1))
|
||||
return SDValue();
|
||||
|
||||
return SDValue(DAG.UpdateNodeOperands(N, Op0, Op1), 0);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_FNEG(SDNode *N) {
|
||||
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
||||
|
||||
if (Op == N->getOperand(0))
|
||||
return SDValue();
|
||||
|
||||
return SDValue(DAG.UpdateNodeOperands(N, Op), 0);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT(SDNode *N) {
|
||||
bool Signed = N->getOpcode() == ISD::FP_TO_SINT;
|
||||
EVT SVT = N->getOperand(0).getValueType();
|
||||
|
@ -1079,30 +951,7 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT(SDNode *N) {
|
|||
return DAG.getNode(ISD::TRUNCATE, dl, RVT, Res);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT(SDNode *N) {
|
||||
SDValue Op1 = GetSoftenedFloat(N->getOperand(1));
|
||||
SDValue Op2 = GetSoftenedFloat(N->getOperand(2));
|
||||
|
||||
if (Op1 == N->getOperand(1) && Op2 == N->getOperand(2))
|
||||
return SDValue();
|
||||
|
||||
return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Op1, Op2),
|
||||
0);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N, unsigned OpNo) {
|
||||
if (OpNo == 2 || OpNo == 3) {
|
||||
SDValue Op2 = GetSoftenedFloat(N->getOperand(2));
|
||||
SDValue Op3 = GetSoftenedFloat(N->getOperand(3));
|
||||
|
||||
if (Op2 == N->getOperand(2) && Op3 == N->getOperand(3))
|
||||
return SDValue();
|
||||
|
||||
return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), N->getOperand(1),
|
||||
Op2, Op3, N->getOperand(4)),
|
||||
0);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) {
|
||||
SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
|
||||
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
|
||||
|
||||
|
|
|
@ -81,7 +81,6 @@ void DAGTypeLegalizer::PerformExpensiveChecks() {
|
|||
|
||||
for (unsigned i = 0, e = Node.getNumValues(); i != e; ++i) {
|
||||
SDValue Res(&Node, i);
|
||||
EVT VT = Res.getValueType();
|
||||
bool Failed = false;
|
||||
// Don't create a value in map.
|
||||
auto ResId = (ValueToIdMap.count(Res)) ? ValueToIdMap[Res] : 0;
|
||||
|
@ -135,17 +134,13 @@ void DAGTypeLegalizer::PerformExpensiveChecks() {
|
|||
dbgs() << "Unprocessed value in a map!";
|
||||
Failed = true;
|
||||
}
|
||||
} else if (isTypeLegal(VT) || IgnoreNodeResults(&Node)) {
|
||||
} else if (isTypeLegal(Res.getValueType()) || IgnoreNodeResults(&Node)) {
|
||||
if (Mapped > 1) {
|
||||
dbgs() << "Value with legal type was transformed!";
|
||||
Failed = true;
|
||||
}
|
||||
} else {
|
||||
// If the value can be kept in HW registers, softening machinery can
|
||||
// leave it unchanged and don't put it to any map.
|
||||
if (Mapped == 0 &&
|
||||
!(getTypeAction(VT) == TargetLowering::TypeSoftenFloat &&
|
||||
isLegalInHWReg(VT))) {
|
||||
if (Mapped == 0) {
|
||||
dbgs() << "Processed value not in any map!";
|
||||
Failed = true;
|
||||
} else if (Mapped & (Mapped - 1)) {
|
||||
|
@ -257,13 +252,9 @@ bool DAGTypeLegalizer::run() {
|
|||
Changed = true;
|
||||
goto NodeDone;
|
||||
case TargetLowering::TypeSoftenFloat:
|
||||
Changed = SoftenFloatResult(N, i);
|
||||
if (Changed)
|
||||
goto NodeDone;
|
||||
// If not changed, the result type should be legally in register.
|
||||
assert(isLegalInHWReg(ResultVT) &&
|
||||
"Unchanged SoftenFloatResult should be legal in register!");
|
||||
goto ScanOperands;
|
||||
SoftenFloatResult(N, i);
|
||||
Changed = true;
|
||||
goto NodeDone;
|
||||
case TargetLowering::TypeExpandFloat:
|
||||
ExpandFloatResult(N, i);
|
||||
Changed = true;
|
||||
|
@ -439,15 +430,9 @@ NodeDone:
|
|||
bool Failed = false;
|
||||
|
||||
// Check that all result types are legal.
|
||||
// A value type is illegal if its TypeAction is not TypeLegal,
|
||||
// and TLI.RegClassForVT does not have a register class for this type.
|
||||
// For example, the x86_64 target has f128 that is not TypeLegal,
|
||||
// to have softened operators, but it also has FR128 register class to
|
||||
// pass and return f128 values. Hence a legalized node can have f128 type.
|
||||
if (!IgnoreNodeResults(&Node))
|
||||
for (unsigned i = 0, NumVals = Node.getNumValues(); i < NumVals; ++i)
|
||||
if (!isTypeLegal(Node.getValueType(i)) &&
|
||||
!TLI.isTypeLegal(Node.getValueType(i))) {
|
||||
if (!isTypeLegal(Node.getValueType(i))) {
|
||||
dbgs() << "Result type " << i << " illegal: ";
|
||||
Node.dump(&DAG);
|
||||
Failed = true;
|
||||
|
@ -456,8 +441,7 @@ NodeDone:
|
|||
// Check that all operand types are legal.
|
||||
for (unsigned i = 0, NumOps = Node.getNumOperands(); i < NumOps; ++i)
|
||||
if (!IgnoreNodeResults(Node.getOperand(i).getNode()) &&
|
||||
!isTypeLegal(Node.getOperand(i).getValueType()) &&
|
||||
!TLI.isTypeLegal(Node.getOperand(i).getValueType())) {
|
||||
!isTypeLegal(Node.getOperand(i).getValueType())) {
|
||||
dbgs() << "Operand type " << i << " illegal: ";
|
||||
Node.getOperand(i).dump(&DAG);
|
||||
Failed = true;
|
||||
|
@ -713,23 +697,13 @@ void DAGTypeLegalizer::SetPromotedInteger(SDValue Op, SDValue Result) {
|
|||
}
|
||||
|
||||
void DAGTypeLegalizer::SetSoftenedFloat(SDValue Op, SDValue Result) {
|
||||
// f128 of x86_64 could be kept in SSE registers,
|
||||
// but sometimes softened to i128.
|
||||
assert((Result.getValueType() ==
|
||||
TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType()) ||
|
||||
Op.getValueType() ==
|
||||
TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType())) &&
|
||||
assert(Result.getValueType() ==
|
||||
TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType()) &&
|
||||
"Invalid type for softened float");
|
||||
AnalyzeNewValue(Result);
|
||||
|
||||
auto &OpIdEntry = SoftenedFloats[getTableId(Op)];
|
||||
// Allow repeated calls to save f128 type nodes
|
||||
// or any node with type that transforms to itself.
|
||||
// Many operations on these types are not softened.
|
||||
assert(((OpIdEntry == 0) ||
|
||||
Op.getValueType() ==
|
||||
TLI.getTypeToTransformTo(*DAG.getContext(), Op.getValueType())) &&
|
||||
"Node is already converted to integer!");
|
||||
assert((OpIdEntry == 0) && "Node is already converted to integer!");
|
||||
OpIdEntry = getTableId(Result);
|
||||
}
|
||||
|
||||
|
|
|
@ -73,15 +73,6 @@ private:
|
|||
return VT.isSimple() && TLI.isTypeLegal(VT);
|
||||
}
|
||||
|
||||
/// Return true if this type can be passed in registers.
|
||||
/// For example, x86_64's f128, should to be legally in registers
|
||||
/// and only some operations converted to library calls or integer
|
||||
/// bitwise operations.
|
||||
bool isLegalInHWReg(EVT VT) const {
|
||||
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
|
||||
return VT == NVT && isSimpleLegalType(VT);
|
||||
}
|
||||
|
||||
EVT getSetCCResultType(EVT VT) const {
|
||||
return TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
|
||||
}
|
||||
|
@ -472,14 +463,11 @@ private:
|
|||
// Float to Integer Conversion Support: LegalizeFloatTypes.cpp
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
/// Given an operand Op of Float type, returns the integer if the Op is not
|
||||
/// supported in target HW and converted to the integer.
|
||||
/// The integer contains exactly the same bits as Op - only the type changed.
|
||||
/// For example, if Op is an f32 which was softened to an i32, then this
|
||||
/// method returns an i32, the bits of which coincide with those of Op.
|
||||
/// If the Op can be efficiently supported in target HW or the operand must
|
||||
/// stay in a register, the Op is not converted to an integer.
|
||||
/// In that case, the given op is returned.
|
||||
/// GetSoftenedFloat - Given a processed operand Op which was converted to an
|
||||
/// integer of the same size, this returns the integer. The integer contains
|
||||
/// exactly the same bits as Op - only the type changed. For example, if Op
|
||||
/// is an f32 which was softened to an i32, then this method returns an i32,
|
||||
/// the bits of which coincide with those of Op
|
||||
SDValue GetSoftenedFloat(SDValue Op) {
|
||||
TableId Id = getTableId(Op);
|
||||
auto Iter = SoftenedFloats.find(Id);
|
||||
|
@ -494,19 +482,19 @@ private:
|
|||
}
|
||||
void SetSoftenedFloat(SDValue Op, SDValue Result);
|
||||
|
||||
// Convert Float Results to Integer for Non-HW-supported Operations.
|
||||
bool SoftenFloatResult(SDNode *N, unsigned ResNo);
|
||||
// Convert Float Results to Integer.
|
||||
void SoftenFloatResult(SDNode *N, unsigned ResNo);
|
||||
SDValue SoftenFloatRes_MERGE_VALUES(SDNode *N, unsigned ResNo);
|
||||
SDValue SoftenFloatRes_BITCAST(SDNode *N, unsigned ResNo);
|
||||
SDValue SoftenFloatRes_BITCAST(SDNode *N);
|
||||
SDValue SoftenFloatRes_BUILD_PAIR(SDNode *N);
|
||||
SDValue SoftenFloatRes_ConstantFP(SDNode *N, unsigned ResNo);
|
||||
SDValue SoftenFloatRes_ConstantFP(SDNode *N);
|
||||
SDValue SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N, unsigned ResNo);
|
||||
SDValue SoftenFloatRes_FABS(SDNode *N, unsigned ResNo);
|
||||
SDValue SoftenFloatRes_FABS(SDNode *N);
|
||||
SDValue SoftenFloatRes_FMINNUM(SDNode *N);
|
||||
SDValue SoftenFloatRes_FMAXNUM(SDNode *N);
|
||||
SDValue SoftenFloatRes_FADD(SDNode *N);
|
||||
SDValue SoftenFloatRes_FCEIL(SDNode *N);
|
||||
SDValue SoftenFloatRes_FCOPYSIGN(SDNode *N, unsigned ResNo);
|
||||
SDValue SoftenFloatRes_FCOPYSIGN(SDNode *N);
|
||||
SDValue SoftenFloatRes_FCOS(SDNode *N);
|
||||
SDValue SoftenFloatRes_FDIV(SDNode *N);
|
||||
SDValue SoftenFloatRes_FEXP(SDNode *N);
|
||||
|
@ -518,7 +506,7 @@ private:
|
|||
SDValue SoftenFloatRes_FMA(SDNode *N);
|
||||
SDValue SoftenFloatRes_FMUL(SDNode *N);
|
||||
SDValue SoftenFloatRes_FNEARBYINT(SDNode *N);
|
||||
SDValue SoftenFloatRes_FNEG(SDNode *N, unsigned ResNo);
|
||||
SDValue SoftenFloatRes_FNEG(SDNode *N);
|
||||
SDValue SoftenFloatRes_FP_EXTEND(SDNode *N);
|
||||
SDValue SoftenFloatRes_FP16_TO_FP(SDNode *N);
|
||||
SDValue SoftenFloatRes_FP_ROUND(SDNode *N);
|
||||
|
@ -531,27 +519,17 @@ private:
|
|||
SDValue SoftenFloatRes_FSQRT(SDNode *N);
|
||||
SDValue SoftenFloatRes_FSUB(SDNode *N);
|
||||
SDValue SoftenFloatRes_FTRUNC(SDNode *N);
|
||||
SDValue SoftenFloatRes_LOAD(SDNode *N, unsigned ResNo);
|
||||
SDValue SoftenFloatRes_SELECT(SDNode *N, unsigned ResNo);
|
||||
SDValue SoftenFloatRes_SELECT_CC(SDNode *N, unsigned ResNo);
|
||||
SDValue SoftenFloatRes_LOAD(SDNode *N);
|
||||
SDValue SoftenFloatRes_SELECT(SDNode *N);
|
||||
SDValue SoftenFloatRes_SELECT_CC(SDNode *N);
|
||||
SDValue SoftenFloatRes_UNDEF(SDNode *N);
|
||||
SDValue SoftenFloatRes_VAARG(SDNode *N);
|
||||
SDValue SoftenFloatRes_XINT_TO_FP(SDNode *N);
|
||||
|
||||
// Return true if we can skip softening the given operand or SDNode because
|
||||
// either it was soften before by SoftenFloatResult and references to the
|
||||
// operand were replaced by ReplaceValueWith or it's value type is legal in HW
|
||||
// registers and the operand can be left unchanged.
|
||||
bool CanSkipSoftenFloatOperand(SDNode *N, unsigned OpNo);
|
||||
|
||||
// Convert Float Operand to Integer for Non-HW-supported Operations.
|
||||
// Convert Float Operand to Integer.
|
||||
bool SoftenFloatOperand(SDNode *N, unsigned OpNo);
|
||||
SDValue SoftenFloatOp_BITCAST(SDNode *N);
|
||||
SDValue SoftenFloatOp_COPY_TO_REG(SDNode *N);
|
||||
SDValue SoftenFloatOp_BR_CC(SDNode *N);
|
||||
SDValue SoftenFloatOp_FABS(SDNode *N);
|
||||
SDValue SoftenFloatOp_FCOPYSIGN(SDNode *N);
|
||||
SDValue SoftenFloatOp_FNEG(SDNode *N);
|
||||
SDValue SoftenFloatOp_FP_EXTEND(SDNode *N);
|
||||
SDValue SoftenFloatOp_FP_ROUND(SDNode *N);
|
||||
SDValue SoftenFloatOp_FP_TO_XINT(SDNode *N);
|
||||
|
@ -559,8 +537,7 @@ private:
|
|||
SDValue SoftenFloatOp_LLROUND(SDNode *N);
|
||||
SDValue SoftenFloatOp_LRINT(SDNode *N);
|
||||
SDValue SoftenFloatOp_LLRINT(SDNode *N);
|
||||
SDValue SoftenFloatOp_SELECT(SDNode *N);
|
||||
SDValue SoftenFloatOp_SELECT_CC(SDNode *N, unsigned OpNo);
|
||||
SDValue SoftenFloatOp_SELECT_CC(SDNode *N);
|
||||
SDValue SoftenFloatOp_SETCC(SDNode *N);
|
||||
SDValue SoftenFloatOp_STORE(SDNode *N, unsigned OpNo);
|
||||
|
||||
|
|
|
@ -52,17 +52,11 @@ void DAGTypeLegalizer::ExpandRes_BITCAST(SDNode *N, SDValue &Lo, SDValue &Hi) {
|
|||
case TargetLowering::TypePromoteFloat:
|
||||
llvm_unreachable("Bitcast of a promotion-needing float should never need"
|
||||
"expansion");
|
||||
case TargetLowering::TypeSoftenFloat: {
|
||||
// Expand the floating point operand only if it was converted to integers.
|
||||
// Otherwise, it is a legal type like f128 that can be saved in a register.
|
||||
auto SoftenedOp = GetSoftenedFloat(InOp);
|
||||
if (isLegalInHWReg(SoftenedOp.getValueType()))
|
||||
break;
|
||||
SplitInteger(SoftenedOp, Lo, Hi);
|
||||
case TargetLowering::TypeSoftenFloat:
|
||||
SplitInteger(GetSoftenedFloat(InOp), Lo, Hi);
|
||||
Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
|
||||
Hi = DAG.getNode(ISD::BITCAST, dl, NOutVT, Hi);
|
||||
return;
|
||||
}
|
||||
case TargetLowering::TypeExpandInteger:
|
||||
case TargetLowering::TypeExpandFloat: {
|
||||
auto &DL = DAG.getDataLayout();
|
||||
|
|
Loading…
Reference in New Issue