X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FLegalizeIntegerTypes.cpp;h=b2c668b7a83f4973cea8cc33b8042cf22781d1f0;hb=cff50d9e20d7bbc3acf4845fe826bfb3095126c4;hp=d4be998be5ed32d4d5d0db868549680059da085a;hpb=ee4c619b3b28a42078fc8033e5dccd42fc6edd42;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index d4be998be5e..b2c668b7a83 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -206,7 +206,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) { case Legal: break; case PromoteInteger: - if (OutVT.getSizeInBits() == NInVT.getSizeInBits()) + if (OutVT.bitsEq(NInVT)) // The input promotes to the same size. Convert the promoted value. return DAG.getNode(ISD::BIT_CONVERT, OutVT, GetPromotedInteger(InOp)); break; @@ -267,7 +267,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_Constant(SDNode *N) { // matter in theory which one we pick, but this tends to give better code? unsigned Opc = VT.isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; SDValue Result = DAG.getNode(Opc, TLI.getTypeToTransformTo(VT), - SDValue(N, 0)); + SDValue(N, 0)); assert(isa(Result) && "Didn't constant fold ext?"); return Result; } @@ -340,8 +340,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) { // Hi if it was odd. SDValue Lo = Elt; SDValue Hi = DAG.getNode(ISD::SRL, NewVT, Elt, - DAG.getConstant(OldVT.getSizeInBits(), - TLI.getShiftAmountTy())); + DAG.getConstant(OldVT.getSizeInBits(), + TLI.getShiftAmountTy())); if (TLI.isBigEndian()) std::swap(Lo, Hi); @@ -350,22 +350,27 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) { } SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) { - unsigned NewOpc = N->getOpcode(); MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + unsigned NewOpc = N->getOpcode(); // If we're promoting a UINT to a larger size, check to see if the new node // will be legal. If it isn't, check to see if FP_TO_SINT is legal, since // we can use that instead. This allows us to generate better code for // FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not // legal, such as PowerPC. - if (N->getOpcode() == ISD::FP_TO_UINT) { - if (!TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) && - (TLI.isOperationLegal(ISD::FP_TO_SINT, NVT) || - TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom)) - NewOpc = ISD::FP_TO_SINT; - } + if (N->getOpcode() == ISD::FP_TO_UINT && + !TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) && + TLI.isOperationLegal(ISD::FP_TO_SINT, NVT)) + NewOpc = ISD::FP_TO_SINT; + + SDValue Res = DAG.getNode(NewOpc, NVT, N->getOperand(0)); - return DAG.getNode(NewOpc, NVT, N->getOperand(0)); + // Assert that the converted value fits in the original type. If it doesn't + // (eg: because the value being converted is too big), then the result of the + // original operation was undefined anyway, so the assert is still correct. + return DAG.getNode(N->getOpcode() == ISD::FP_TO_UINT ? + ISD::AssertZext : ISD::AssertSext, + NVT, Res, DAG.getValueType(N->getValueType(0))); } SDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) { @@ -373,8 +378,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) { if (getTypeAction(N->getOperand(0).getValueType()) == PromoteInteger) { SDValue Res = GetPromotedInteger(N->getOperand(0)); - assert(Res.getValueType().getSizeInBits() <= NVT.getSizeInBits() && - "Extension doesn't make sense!"); + assert(Res.getValueType().bitsLE(NVT) && "Extension doesn't make sense!"); // If the result and operand types are the same after promotion, simplify // to an in-register extension. @@ -446,8 +450,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) { // Convert to the expected type. MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - assert(NVT.getSizeInBits() <= SVT.getSizeInBits() && - "Integer type overpromoted?"); + assert(NVT.bitsLE(SVT) && "Integer type overpromoted?"); return DAG.getNode(ISD::TRUNCATE, NVT, SetCC); } @@ -489,6 +492,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) { } SDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue Res; switch (getTypeAction(N->getOperand(0).getValueType())) { @@ -502,12 +506,6 @@ SDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) { break; } - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - assert(Res.getValueType().getSizeInBits() >= NVT.getSizeInBits() && - "Truncation doesn't make sense!"); - if (Res.getValueType() == NVT) - return Res; - // Truncate to NVT instead of VT return DAG.getNode(ISD::TRUNCATE, NVT, Res); } @@ -532,29 +530,37 @@ SDValue DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) { SDValue Ptr = N->getOperand(1); // Get the pointer. MVT VT = N->getValueType(0); - const Value *V = cast(N->getOperand(2))->getValue(); - SDValue VAList = DAG.getLoad(TLI.getPointerTy(), Chain, Ptr, V, 0); + MVT RegVT = TLI.getRegisterType(VT); + unsigned NumRegs = TLI.getNumRegisters(VT); + // The argument is passed as NumRegs registers of type RegVT. - // Increment the arg pointer, VAList, to the next vaarg - // FIXME: should the ABI size be used for the increment? Think of - // x86 long double (10 bytes long, but aligned on 4 or 8 bytes) or - // integers of unusual size (such MVT::i1, which gives an increment - // of zero here!). - unsigned Increment = VT.getSizeInBits() / 8; - SDValue Tmp = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList, - DAG.getIntPtrConstant(Increment)); + SmallVector Parts(NumRegs); + for (unsigned i = 0; i < NumRegs; ++i) { + Parts[i] = DAG.getVAArg(RegVT, Chain, Ptr, N->getOperand(2)); + Chain = Parts[i].getValue(1); + } - // Store the incremented VAList to the pointer. - Tmp = DAG.getStore(VAList.getValue(1), Tmp, Ptr, V, 0); + // Handle endianness of the load. + if (TLI.isBigEndian()) + std::reverse(Parts.begin(), Parts.end()); - // Load the actual argument out of the arg pointer VAList. - Tmp = DAG.getExtLoad(ISD::EXTLOAD, TLI.getTypeToTransformTo(VT), Tmp, - VAList, NULL, 0, VT); + // Assemble the parts in the promoted type. + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Res = DAG.getNode(ISD::ZERO_EXTEND, NVT, Parts[0]); + for (unsigned i = 1; i < NumRegs; ++i) { + SDValue Part = DAG.getNode(ISD::ZERO_EXTEND, NVT, Parts[i]); + // Shift it to the right position and "or" it in. + Part = DAG.getNode(ISD::SHL, NVT, Part, + DAG.getConstant(i * RegVT.getSizeInBits(), + TLI.getShiftAmountTy())); + Res = DAG.getNode(ISD::OR, NVT, Res, Part); + } - // Legalized the chain result - switch anything that used the old chain to + // Modified the chain result - switch anything that used the old chain to // use the new one. - ReplaceValueWith(SDValue(N, 1), Tmp.getValue(1)); - return Tmp; + ReplaceValueWith(SDValue(N, 1), Chain); + + return Res; } @@ -636,10 +642,9 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS, NewLHS = GetPromotedInteger(NewLHS); NewRHS = GetPromotedInteger(NewRHS); - // Otherwise, 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. + // 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. switch (CCCode) { default: assert(0 && "Unknown integer comparison!"); case ISD::SETEQ: @@ -688,12 +693,25 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo) { assert(OpNo == 1 && "only know how to promote condition"); SDValue Cond = GetPromotedInteger(N->getOperand(1)); // Promote condition. - // The top bits of the promoted condition are not necessarily zero, ensure - // that the value is properly zero extended. - unsigned BitWidth = Cond.getValueSizeInBits(); - if (!DAG.MaskedValueIsZero(Cond, - APInt::getHighBitsSet(BitWidth, BitWidth-1))) - Cond = DAG.getZeroExtendInReg(Cond, MVT::i1); + // Make sure the extra bits coming from type promotion conform to + // getSetCCResultContents. + unsigned CondBits = Cond.getValueSizeInBits(); + switch (TLI.getSetCCResultContents()) { + default: + assert(false && "Unknown SetCCResultValue!"); + case TargetLowering::UndefinedSetCCResult: + // The promoted value, which may contain rubbish in the upper bits, is fine. + break; + case TargetLowering::ZeroOrOneSetCCResult: + if (!DAG.MaskedValueIsZero(Cond,APInt::getHighBitsSet(CondBits,CondBits-1))) + Cond = DAG.getZeroExtendInReg(Cond, MVT::i1); + break; + case TargetLowering::ZeroOrNegativeOneSetCCResult: + if (DAG.ComputeNumSignBits(Cond) != CondBits) + Cond = DAG.getNode(ISD::SIGN_EXTEND_INREG, Cond.getValueType(), Cond, + DAG.getValueType(MVT::i1)); + break; + } // The chain (Op#0) and basic block destination (Op#2) are always legal types. return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), Cond, @@ -819,8 +837,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) { // around the problem. MVT SVT = TLI.getSetCCResultType(N->getOperand(1)); assert(isTypeLegal(SVT) && "Illegal SetCC type!"); - assert(Cond.getValueSizeInBits() <= SVT.getSizeInBits() && - "Unexpected SetCC type!"); + assert(Cond.getValueType().bitsLE(SVT) && "Unexpected SetCC type!"); // Make sure the extra bits conform to getSetCCResultContents. There are // two sets of extra bits: those in Cond, which come from type promotion, @@ -960,6 +977,7 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) { case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break; case ISD::EXTRACT_ELEMENT: ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break; case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break; + case ISD::VAARG: ExpandRes_VAARG(N, Lo, Hi); break; case ISD::ANY_EXTEND: ExpandIntRes_ANY_EXTEND(N, Lo, Hi); break; case ISD::AssertSext: ExpandIntRes_AssertSext(N, Lo, Hi); break; @@ -1708,7 +1726,7 @@ void DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N, MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue Op = N->getOperand(0); if (Op.getValueType().bitsLE(NVT)) { - // The low part is sign extension of the input (which degenerates to a copy). + // The low part is sign extension of the input (degenerates to a copy). Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, N->getOperand(0)); // The high part is obtained by SRA'ing all but one of the bits of low part. unsigned LoSize = NVT.getSizeInBits(); @@ -1822,7 +1840,7 @@ void DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N, MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue Op = N->getOperand(0); if (Op.getValueType().bitsLE(NVT)) { - // The low part is zero extension of the input (which degenerates to a copy). + // The low part is zero extension of the input (degenerates to a copy). Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, N->getOperand(0)); Hi = DAG.getConstant(0, NVT); // The high part is just a zero. } else {