SDValue Result = SDValue();
// See if the target wants to custom expand this node.
- if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) ==
- TargetLowering::Custom) {
- // If the target wants to, allow it to lower this itself.
- if (SDNode *P = TLI.ReplaceNodeResults(N, DAG)) {
- // Everything that once used N now uses P. We are guaranteed that the
- // result value types of N and the result value types of P match.
- ReplaceNodeWith(N, P);
- return;
- }
- }
+ if (CustomLowerResults(N, ResNo))
+ return;
switch (N->getOpcode()) {
default:
case ISD::ANY_EXTEND: Result = PromoteIntRes_INT_EXTEND(N); break;
case ISD::FP_TO_SINT:
- case ISD::FP_TO_UINT: Result = PromoteIntRes_FP_TO_XINT(N); break;
+ case ISD::FP_TO_UINT: Result = PromoteIntRes_FP_TO_XINT(N); break;
case ISD::AND:
case ISD::OR:
case ISD::XOR:
case ISD::ADD:
case ISD::SUB:
- case ISD::MUL: Result = PromoteIntRes_SimpleIntBinOp(N); break;
+ case ISD::MUL: Result = PromoteIntRes_SimpleIntBinOp(N); break;
case ISD::SDIV:
- case ISD::SREM: Result = PromoteIntRes_SDIV(N); break;
+ case ISD::SREM: Result = PromoteIntRes_SDIV(N); break;
case ISD::UDIV:
- case ISD::UREM: Result = PromoteIntRes_UDIV(N); break;
+ case ISD::UREM: Result = PromoteIntRes_UDIV(N); break;
+
+ case ISD::SADDO:
+ case ISD::UADDO: Result = PromoteIntRes_XADDO(N, ResNo); break;
case ISD::ATOMIC_LOAD_ADD_8:
case ISD::ATOMIC_LOAD_SUB_8:
SDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) {
// Sign-extend the new bits, and continue the assertion.
- MVT OldVT = N->getValueType(0);
- SDValue Op = GetPromotedInteger(N->getOperand(0));
- return DAG.getNode(ISD::AssertSext, Op.getValueType(),
- DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(), Op,
- DAG.getValueType(OldVT)), N->getOperand(1));
+ SDValue Op = SExtPromotedInteger(N->getOperand(0));
+ return DAG.getNode(ISD::AssertSext, Op.getValueType(), Op, N->getOperand(1));
}
SDValue DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) {
// Zero the new bits, and continue the assertion.
- MVT OldVT = N->getValueType(0);
- SDValue Op = GetPromotedInteger(N->getOperand(0));
- return DAG.getNode(ISD::AssertZext, Op.getValueType(),
- DAG.getZeroExtendInReg(Op, OldVT), N->getOperand(1));
+ SDValue Op = ZExtPromotedInteger(N->getOperand(0));
+ return DAG.getNode(ISD::AssertZext, Op.getValueType(), Op, N->getOperand(1));
}
SDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) {
SDValue InOp = N->getOperand(0);
MVT InVT = InOp.getValueType();
MVT NInVT = TLI.getTypeToTransformTo(InVT);
- MVT OutVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ MVT OutVT = N->getValueType(0);
+ MVT NOutVT = TLI.getTypeToTransformTo(OutVT);
switch (getTypeAction(InVT)) {
default:
case Legal:
break;
case PromoteInteger:
- if (OutVT.bitsEq(NInVT))
+ if (NOutVT.bitsEq(NInVT))
// The input promotes to the same size. Convert the promoted value.
- return DAG.getNode(ISD::BIT_CONVERT, OutVT, GetPromotedInteger(InOp));
+ return DAG.getNode(ISD::BIT_CONVERT, NOutVT, GetPromotedInteger(InOp));
break;
case SoftenFloat:
// Promote the integer operand by hand.
- return DAG.getNode(ISD::ANY_EXTEND, OutVT, GetSoftenedFloat(InOp));
+ return DAG.getNode(ISD::ANY_EXTEND, NOutVT, GetSoftenedFloat(InOp));
case ExpandInteger:
case ExpandFloat:
break;
case ScalarizeVector:
// Convert the element to an integer and promote it by hand.
- return DAG.getNode(ISD::ANY_EXTEND, OutVT,
+ return DAG.getNode(ISD::ANY_EXTEND, NOutVT,
BitConvertToInteger(GetScalarizedVector(InOp)));
case SplitVector:
// For example, i32 = BIT_CONVERT v2i16 on alpha. Convert the split
std::swap(Lo, Hi);
InOp = DAG.getNode(ISD::ANY_EXTEND,
- MVT::getIntegerVT(OutVT.getSizeInBits()),
+ MVT::getIntegerVT(NOutVT.getSizeInBits()),
JoinIntegers(Lo, Hi));
- return DAG.getNode(ISD::BIT_CONVERT, OutVT, InOp);
+ return DAG.getNode(ISD::BIT_CONVERT, NOutVT, InOp);
}
- // Otherwise, lower the bit-convert to a store/load from the stack, then
- // promote the load.
- SDValue Op = CreateStackStoreLoad(InOp, N->getValueType(0));
- return PromoteIntRes_LOAD(cast<LoadSDNode>(Op.getNode()));
+ // Otherwise, lower the bit-convert to a store/load from the stack.
+
+ // Create the stack frame object. Make sure it is aligned for both
+ // the source and destination types.
+ SDValue FIPtr = DAG.CreateStackTemporary(InVT, OutVT);
+
+ // Emit a store to the stack slot.
+ SDValue Store = DAG.getStore(DAG.getEntryNode(), InOp, FIPtr, NULL, 0);
+
+ // Result is an extending load from the stack slot.
+ return DAG.getExtLoad(ISD::EXTLOAD, NOutVT, Store, FIPtr, NULL, 0, OutVT);
}
SDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) {
}
SDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) {
- SDValue Op = GetPromotedInteger(N->getOperand(0));
+ // Zero extend to the promoted type and do the count there.
+ SDValue Op = ZExtPromotedInteger(N->getOperand(0));
MVT OVT = N->getValueType(0);
MVT NVT = Op.getValueType();
- // Zero extend to the promoted type and do the count there.
- Op = DAG.getNode(ISD::CTLZ, NVT, DAG.getZeroExtendInReg(Op, OVT));
+ Op = DAG.getNode(ISD::CTLZ, NVT, Op);
// Subtract off the extra leading bits in the bigger type.
return DAG.getNode(ISD::SUB, NVT, Op,
DAG.getConstant(NVT.getSizeInBits() -
}
SDValue DAGTypeLegalizer::PromoteIntRes_CTPOP(SDNode *N) {
- SDValue Op = GetPromotedInteger(N->getOperand(0));
- MVT OVT = N->getValueType(0);
- MVT NVT = Op.getValueType();
// Zero extend to the promoted type and do the count there.
- return DAG.getNode(ISD::CTPOP, NVT, DAG.getZeroExtendInReg(Op, OVT));
+ SDValue Op = ZExtPromotedInteger(N->getOperand(0));
+ return DAG.getNode(ISD::CTPOP, Op.getValueType(), Op);
}
SDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) {
ISD::LoadExtType ExtType =
ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType();
SDValue Res = DAG.getExtLoad(ExtType, NVT, N->getChain(), N->getBasePtr(),
- N->getSrcValue(), N->getSrcValueOffset(),
- N->getMemoryVT(), N->isVolatile(),
- N->getAlignment());
+ N->getSrcValue(), N->getSrcValueOffset(),
+ N->getMemoryVT(), N->isVolatile(),
+ N->getAlignment());
// Legalized the chain result - switch anything that used the old chain to
// use the new one.
SDValue DAGTypeLegalizer::PromoteIntRes_SDIV(SDNode *N) {
// Sign extend the input.
- SDValue LHS = GetPromotedInteger(N->getOperand(0));
- SDValue RHS = GetPromotedInteger(N->getOperand(1));
- MVT VT = N->getValueType(0);
- LHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, LHS.getValueType(), LHS,
- DAG.getValueType(VT));
- RHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, RHS.getValueType(), RHS,
- DAG.getValueType(VT));
-
+ SDValue LHS = SExtPromotedInteger(N->getOperand(0));
+ SDValue RHS = SExtPromotedInteger(N->getOperand(1));
return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
}
SDValue DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) {
// The input value must be properly sign extended.
- MVT VT = N->getValueType(0);
- MVT NVT = TLI.getTypeToTransformTo(VT);
- SDValue Res = GetPromotedInteger(N->getOperand(0));
- Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, DAG.getValueType(VT));
- return DAG.getNode(ISD::SRA, NVT, Res, N->getOperand(1));
+ SDValue Res = SExtPromotedInteger(N->getOperand(0));
+ return DAG.getNode(ISD::SRA, Res.getValueType(), Res, N->getOperand(1));
}
SDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) {
SDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) {
// Zero extend the input.
- SDValue LHS = GetPromotedInteger(N->getOperand(0));
- SDValue RHS = GetPromotedInteger(N->getOperand(1));
- MVT VT = N->getValueType(0);
- LHS = DAG.getZeroExtendInReg(LHS, VT);
- RHS = DAG.getZeroExtendInReg(RHS, VT);
-
+ SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
+ SDValue RHS = ZExtPromotedInteger(N->getOperand(1));
return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
}
+SDValue DAGTypeLegalizer::PromoteIntRes_XADDO(SDNode *N, unsigned ResNo) {
+ assert(ResNo == 1 && "Only boolean result promotion currently supported!");
+
+ // Simply change the return type of the boolean result.
+ MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1));
+ MVT ValueVTs[] = { N->getValueType(0), NVT };
+ SDValue Ops[] = { N->getOperand(0), N->getOperand(1) };
+ SDValue Res = DAG.getNode(N->getOpcode(), DAG.getVTList(ValueVTs, 2), Ops, 2);
+
+ // Modified the sum result - switch anything that used the old sum to use
+ // the new one.
+ ReplaceValueWith(SDValue(N, 0), Res);
+
+ return SDValue(Res.getNode(), 1);
+}
+
SDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) {
return DAG.getNode(ISD::UNDEF, TLI.getTypeToTransformTo(N->getValueType(0)));
}
case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break;
case ISD::CONVERT_RNDSAT:
Res = PromoteIntOp_CONVERT_RNDSAT(N); break;
- case ISD::FP_EXTEND: Res = PromoteIntOp_FP_EXTEND(N); break;
- case ISD::FP_ROUND: Res = PromoteIntOp_FP_ROUND(N); break;
case ISD::INSERT_VECTOR_ELT:
Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo);break;
case ISD::MEMBARRIER: Res = PromoteIntOp_MEMBARRIER(N); break;
case ISD::SELECT_CC: Res = PromoteIntOp_SELECT_CC(N, OpNo); break;
case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break;
case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break;
+ case ISD::SINT_TO_FP: Res = PromoteIntOp_SINT_TO_FP(N); break;
case ISD::STORE: Res = PromoteIntOp_STORE(cast<StoreSDNode>(N),
OpNo); break;
case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break;
+ case ISD::UINT_TO_FP: Res = PromoteIntOp_UINT_TO_FP(N); break;
case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break;
-
- case ISD::SINT_TO_FP:
- case ISD::UINT_TO_FP: Res = PromoteIntOp_INT_TO_FP(N); break;
}
}
// If the result is null, the sub-method took care of registering results etc.
if (!Res.getNode()) return false;
- // If the result is N, the sub-method updated N in place.
- if (Res.getNode() == N) {
- // Mark N as new and remark N and its operands. This allows us to correctly
- // revisit N if it needs another step of promotion and allows us to visit
- // any new operands to N.
- ReanalyzeNode(N);
+
+ // If the result is N, the sub-method updated N in place. Tell the legalizer
+ // core about this.
+ if (Res.getNode() == N)
return true;
- }
assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
"Invalid operand expansion");
/// shared among BR_CC, SELECT_CC, and SETCC handlers.
void DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS,
ISD::CondCode CCCode) {
- MVT VT = NewLHS.getValueType();
-
- // Get the promoted values.
- NewLHS = GetPromotedInteger(NewLHS);
- NewRHS = GetPromotedInteger(NewRHS);
-
// We have to insert explicit sign or zero extends. Note that we could
// insert sign extends for ALL conditions, but zero extend is cheaper on
// many machines (an AND instead of two shifts), so prefer it.
// ALL of these operations will work if we either sign or zero extend
// the operands (including the unsigned comparisons!). Zero extend is
// usually a simpler/cheaper operation, so prefer it.
- NewLHS = DAG.getZeroExtendInReg(NewLHS, VT);
- NewRHS = DAG.getZeroExtendInReg(NewRHS, VT);
+ NewLHS = ZExtPromotedInteger(NewLHS);
+ NewRHS = ZExtPromotedInteger(NewRHS);
break;
case ISD::SETGE:
case ISD::SETGT:
case ISD::SETLT:
case ISD::SETLE:
- NewLHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewLHS.getValueType(), NewLHS,
- DAG.getValueType(VT));
- NewRHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewRHS.getValueType(), NewRHS,
- DAG.getValueType(VT));
+ NewLHS = SExtPromotedInteger(NewLHS);
+ NewRHS = SExtPromotedInteger(NewRHS);
break;
}
}
SDValue Cond = GetPromotedInteger(N->getOperand(1)); // Promote condition.
// Make sure the extra bits coming from type promotion conform to
- // getSetCCResultContents.
+ // getBooleanContents.
unsigned CondBits = Cond.getValueSizeInBits();
- switch (TLI.getSetCCResultContents()) {
+ switch (TLI.getBooleanContents()) {
default:
- assert(false && "Unknown SetCCResultValue!");
- case TargetLowering::UndefinedSetCCResult:
+ assert(false && "Unknown BooleanContent!");
+ case TargetLowering::UndefinedBooleanContent:
// The promoted value, which may contain rubbish in the upper bits, is fine.
break;
- case TargetLowering::ZeroOrOneSetCCResult:
+ case TargetLowering::ZeroOrOneBooleanContent:
if (!DAG.MaskedValueIsZero(Cond,APInt::getHighBitsSet(CondBits,CondBits-1)))
Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
break;
- case TargetLowering::ZeroOrNegativeOneSetCCResult:
+ case TargetLowering::ZeroOrNegativeOneBooleanContent:
if (DAG.ComputeNumSignBits(Cond) != CondBits)
Cond = DAG.getNode(ISD::SIGN_EXTEND_INREG, Cond.getValueType(), Cond,
DAG.getValueType(MVT::i1));
SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_PAIR(SDNode *N) {
// Since the result type is legal, the operands must promote to it.
MVT OVT = N->getOperand(0).getValueType();
- SDValue Lo = GetPromotedInteger(N->getOperand(0));
+ SDValue Lo = ZExtPromotedInteger(N->getOperand(0));
SDValue Hi = GetPromotedInteger(N->getOperand(1));
assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?");
- Lo = DAG.getZeroExtendInReg(Lo, OVT);
Hi = DAG.getNode(ISD::SHL, N->getValueType(0), Hi,
DAG.getConstant(OVT.getSizeInBits(),
TLI.getShiftAmountTy()));
N->getOperand(3), N->getOperand(4), CvtCode);
}
-SDValue DAGTypeLegalizer::PromoteIntOp_FP_EXTEND(SDNode *N) {
- SDValue Op = GetPromotedInteger(N->getOperand(0));
- return DAG.getNode(ISD::FP_EXTEND, N->getValueType(0), Op);
-}
-
-SDValue DAGTypeLegalizer::PromoteIntOp_FP_ROUND(SDNode *N) {
- SDValue Op = GetPromotedInteger(N->getOperand(0));
- return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Op,
- DAG.getIntPtrConstant(0));
-}
-
SDValue DAGTypeLegalizer::PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N,
unsigned OpNo) {
if (OpNo == 1) {
assert(OpNo == 2 && "Different operand and result vector types?");
// Promote the index.
- SDValue Idx = N->getOperand(2);
- Idx = DAG.getZeroExtendInReg(GetPromotedInteger(Idx), Idx.getValueType());
+ SDValue Idx = ZExtPromotedInteger(N->getOperand(2));
return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
N->getOperand(1), Idx);
}
-SDValue DAGTypeLegalizer::PromoteIntOp_INT_TO_FP(SDNode *N) {
- SDValue In = GetPromotedInteger(N->getOperand(0));
- MVT OpVT = N->getOperand(0).getValueType();
- if (N->getOpcode() == ISD::UINT_TO_FP)
- In = DAG.getZeroExtendInReg(In, OpVT);
- else
- In = DAG.getNode(ISD::SIGN_EXTEND_INREG, In.getValueType(),
- In, DAG.getValueType(OpVT));
-
- return DAG.UpdateNodeOperands(SDValue(N, 0), In);
-}
-
SDValue DAGTypeLegalizer::PromoteIntOp_MEMBARRIER(SDNode *N) {
SDValue NewOps[6];
NewOps[0] = N->getOperand(0);
assert(isTypeLegal(SVT) && "Illegal SetCC type!");
assert(Cond.getValueType().bitsLE(SVT) && "Unexpected SetCC type!");
- // Make sure the extra bits conform to getSetCCResultContents. There are
+ // Make sure the extra bits conform to getBooleanContents. There are
// two sets of extra bits: those in Cond, which come from type promotion,
// and those we need to add to have the final type be SVT (for most targets
// this last set of bits is empty).
unsigned CondBits = Cond.getValueSizeInBits();
ISD::NodeType ExtendCode;
- switch (TLI.getSetCCResultContents()) {
+ switch (TLI.getBooleanContents()) {
default:
- assert(false && "Unknown SetCCResultValue!");
- case TargetLowering::UndefinedSetCCResult:
+ assert(false && "Unknown BooleanContent!");
+ case TargetLowering::UndefinedBooleanContent:
// Extend to SVT by adding rubbish.
ExtendCode = ISD::ANY_EXTEND;
break;
- case TargetLowering::ZeroOrOneSetCCResult:
+ case TargetLowering::ZeroOrOneBooleanContent:
ExtendCode = ISD::ZERO_EXTEND;
if (!DAG.MaskedValueIsZero(Cond,APInt::getHighBitsSet(CondBits,CondBits-1)))
// All extra bits need to be cleared. Do this by zero extending the
// original condition value all the way to SVT.
Cond = N->getOperand(0);
break;
- case TargetLowering::ZeroOrNegativeOneSetCCResult: {
+ case TargetLowering::ZeroOrNegativeOneBooleanContent: {
ExtendCode = ISD::SIGN_EXTEND;
unsigned SignBits = DAG.ComputeNumSignBits(Cond);
if (SignBits != CondBits)
Op, DAG.getValueType(N->getOperand(0).getValueType()));
}
+SDValue DAGTypeLegalizer::PromoteIntOp_SINT_TO_FP(SDNode *N) {
+ return DAG.UpdateNodeOperands(SDValue(N, 0),
+ SExtPromotedInteger(N->getOperand(0)));
+}
+
SDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
SDValue Ch = N->getChain(), Ptr = N->getBasePtr();
return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), Op);
}
+SDValue DAGTypeLegalizer::PromoteIntOp_UINT_TO_FP(SDNode *N) {
+ return DAG.UpdateNodeOperands(SDValue(N, 0),
+ ZExtPromotedInteger(N->getOperand(0)));
+}
+
SDValue DAGTypeLegalizer::PromoteIntOp_ZERO_EXTEND(SDNode *N) {
SDValue Op = GetPromotedInteger(N->getOperand(0));
Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
Lo = Hi = SDValue();
// See if the target wants to custom expand this node.
- if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) ==
- TargetLowering::Custom) {
- // If the target wants to, allow it to lower this itself.
- if (SDNode *P = TLI.ReplaceNodeResults(N, DAG)) {
- // Everything that once used N now uses P. We are guaranteed that the
- // result value types of N and the result value types of P match.
- ReplaceNodeWith(N, P);
- return;
- }
- }
+ if (CustomLowerResults(N, ResNo))
+ return;
switch (N->getOpcode()) {
default:
} else if (Amt == NVTBits) {
Lo = DAG.getConstant(0, NVT);
Hi = InL;
- } else if (Amt == 1) {
+ } else if (Amt == 1 &&
+ TLI.isOperationLegal(ISD::ADDC, TLI.getTypeToExpandTo(NVT))) {
// Emit this X << 1 as X+X.
SDVTList VTList = DAG.getVTList(NVT, MVT::Flag);
SDValue LoOps[2] = { InL, InL };
// If the result is null, the sub-method took care of registering results etc.
if (!Res.getNode()) return false;
- // If the result is N, the sub-method updated N in place. Check to see if any
- // operands are new, and if so, mark them.
- if (Res.getNode() == N) {
- // Mark N as new and remark N and its operands. This allows us to correctly
- // revisit N if it needs another step of expansion and allows us to visit
- // any new operands to N.
- ReanalyzeNode(N);
+
+ // If the result is N, the sub-method updated N in place. Tell the legalizer
+ // core about this.
+ if (Res.getNode() == N)
return true;
- }
assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
"Invalid operand expansion");