X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FLegalizeIntegerTypes.cpp;h=b2c668b7a83f4973cea8cc33b8042cf22781d1f0;hb=cff50d9e20d7bbc3acf4845fe826bfb3095126c4;hp=7fea9c8a8c35d7e546d05a7c72ee73ca7f5a7310;hpb=f5aeb1a8e4cf272c7348376d185ef8d8267653e0;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 7fea9c8a8c3..b2c668b7a83 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -89,13 +89,65 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { 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::ATOMIC_LOAD_ADD_8: + case ISD::ATOMIC_LOAD_SUB_8: + case ISD::ATOMIC_LOAD_AND_8: + case ISD::ATOMIC_LOAD_OR_8: + case ISD::ATOMIC_LOAD_XOR_8: + case ISD::ATOMIC_LOAD_NAND_8: + case ISD::ATOMIC_LOAD_MIN_8: + case ISD::ATOMIC_LOAD_MAX_8: + case ISD::ATOMIC_LOAD_UMIN_8: + case ISD::ATOMIC_LOAD_UMAX_8: + case ISD::ATOMIC_SWAP_8: + case ISD::ATOMIC_LOAD_ADD_16: + case ISD::ATOMIC_LOAD_SUB_16: + case ISD::ATOMIC_LOAD_AND_16: + case ISD::ATOMIC_LOAD_OR_16: + case ISD::ATOMIC_LOAD_XOR_16: + case ISD::ATOMIC_LOAD_NAND_16: + case ISD::ATOMIC_LOAD_MIN_16: + case ISD::ATOMIC_LOAD_MAX_16: + case ISD::ATOMIC_LOAD_UMIN_16: + case ISD::ATOMIC_LOAD_UMAX_16: + case ISD::ATOMIC_SWAP_16: + case ISD::ATOMIC_LOAD_ADD_32: + case ISD::ATOMIC_LOAD_SUB_32: + case ISD::ATOMIC_LOAD_AND_32: + case ISD::ATOMIC_LOAD_OR_32: + case ISD::ATOMIC_LOAD_XOR_32: + case ISD::ATOMIC_LOAD_NAND_32: + case ISD::ATOMIC_LOAD_MIN_32: + case ISD::ATOMIC_LOAD_MAX_32: + case ISD::ATOMIC_LOAD_UMIN_32: + case ISD::ATOMIC_LOAD_UMAX_32: + case ISD::ATOMIC_SWAP_32: + case ISD::ATOMIC_LOAD_ADD_64: + case ISD::ATOMIC_LOAD_SUB_64: + case ISD::ATOMIC_LOAD_AND_64: + case ISD::ATOMIC_LOAD_OR_64: + case ISD::ATOMIC_LOAD_XOR_64: + case ISD::ATOMIC_LOAD_NAND_64: + case ISD::ATOMIC_LOAD_MIN_64: + case ISD::ATOMIC_LOAD_MAX_64: + case ISD::ATOMIC_LOAD_UMIN_64: + case ISD::ATOMIC_LOAD_UMAX_64: + case ISD::ATOMIC_SWAP_64: + Result = PromoteIntRes_Atomic1(cast(N)); break; + + case ISD::ATOMIC_CMP_SWAP_8: + case ISD::ATOMIC_CMP_SWAP_16: + case ISD::ATOMIC_CMP_SWAP_32: + case ISD::ATOMIC_CMP_SWAP_64: + Result = PromoteIntRes_Atomic2(cast(N)); break; } // If Result is null, the sub-method took care of registering the result. @@ -120,6 +172,27 @@ SDValue DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) { DAG.getZeroExtendInReg(Op, OldVT), N->getOperand(1)); } +SDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) { + SDValue Op2 = GetPromotedInteger(N->getOperand(2)); + SDValue Res = DAG.getAtomic(N->getOpcode(), N->getChain(), N->getBasePtr(), + Op2, N->getSrcValue(), N->getAlignment()); + // Legalized the chain result - switch anything that used the old chain to + // use the new one. + ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); + return Res; +} + +SDValue DAGTypeLegalizer::PromoteIntRes_Atomic2(AtomicSDNode *N) { + SDValue Op2 = GetPromotedInteger(N->getOperand(2)); + SDValue Op3 = GetPromotedInteger(N->getOperand(3)); + SDValue Res = DAG.getAtomic(N->getOpcode(), N->getChain(), N->getBasePtr(), + Op2, Op3, N->getSrcValue(), N->getAlignment()); + // Legalized the chain result - switch anything that used the old chain to + // use the new one. + ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); + return Res; +} + SDValue DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) { SDValue InOp = N->getOperand(0); MVT InVT = InOp.getValueType(); @@ -133,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; @@ -194,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; } @@ -267,33 +340,37 @@ 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); - SDValue Odd = DAG.getNode(ISD::AND, OldIdx.getValueType(), OldIdx, - DAG.getConstant(1, TLI.getShiftAmountTy())); + SDValue Odd = DAG.getNode(ISD::TRUNCATE, MVT::i1, OldIdx); return DAG.getNode(ISD::SELECT, NewVT, Odd, Hi, Lo); } 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; - return DAG.getNode(NewOpc, NVT, N->getOperand(0)); + SDValue Res = 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) { @@ -301,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. @@ -365,10 +441,17 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) { } SDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) { - assert(isTypeLegal(TLI.getSetCCResultType(N->getOperand(0))) - && "SetCC type is not legal??"); - return DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(N->getOperand(0)), - N->getOperand(0), N->getOperand(1), N->getOperand(2)); + MVT SVT = TLI.getSetCCResultType(N->getOperand(0)); + assert(isTypeLegal(SVT) && "Illegal SetCC type!"); + + // Get the SETCC result using the canonical SETCC type. + SDValue SetCC = DAG.getNode(ISD::SETCC, SVT, N->getOperand(0), + N->getOperand(1), N->getOperand(2)); + + // Convert to the expected type. + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + assert(NVT.bitsLE(SVT) && "Integer type overpromoted?"); + return DAG.getNode(ISD::TRUNCATE, NVT, SetCC); } SDValue DAGTypeLegalizer::PromoteIntRes_SHL(SDNode *N) { @@ -409,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())) { @@ -422,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); } @@ -452,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.getConstant(Increment, TLI.getPointerTy())); + 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; } @@ -492,7 +578,7 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) { if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) == TargetLowering::Custom) - Res = TLI.LowerOperation(SDValue(N, OpNo), DAG); + Res = TLI.LowerOperation(SDValue(N, 0), DAG); if (Res.getNode() == 0) { switch (N->getOpcode()) { @@ -556,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: @@ -608,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, @@ -728,18 +826,53 @@ SDValue DAGTypeLegalizer::PromoteIntOp_MEMBARRIER(SDNode *N) { SDValue DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) { assert(OpNo == 0 && "Only know how to promote condition"); - SDValue Cond = GetPromotedInteger(N->getOperand(0)); // 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); + SDValue Cond = GetPromotedInteger(N->getOperand(0)); + + // Promote all the way up to SVT, the canonical SetCC type. + // FIXME: Not clear what value to pass to getSetCCResultType. + // [This only matters for CellSPU since all other targets + // ignore the argument.] We used to pass Cond, resulting in + // SVT = MVT::i8, but CellSPU has no select patterns for i8, + // causing an abort later. Passing the result type works + // around the problem. + MVT SVT = TLI.getSetCCResultType(N->getOperand(1)); + assert(isTypeLegal(SVT) && "Illegal 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, + // 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()) { + default: + assert(false && "Unknown SetCCResultValue!"); + case TargetLowering::UndefinedSetCCResult: + // Extend to SVT by adding rubbish. + ExtendCode = ISD::ANY_EXTEND; + break; + case TargetLowering::ZeroOrOneSetCCResult: + 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: { + ExtendCode = ISD::SIGN_EXTEND; + unsigned SignBits = DAG.ComputeNumSignBits(Cond); + if (SignBits != CondBits) + // All extra bits need to be sign extended. Do this by sign extending the + // original condition value all the way to SVT. + Cond = N->getOperand(0); + break; + } + } + Cond = DAG.getNode(ExtendCode, SVT, Cond); - // The chain (Op#0) and basic block destination (Op#2) are always legal types. - return DAG.UpdateNodeOperands(SDValue(N, 0), Cond, N->getOperand(1), - N->getOperand(2)); + return DAG.UpdateNodeOperands(SDValue(N, 0), Cond, + N->getOperand(1), N->getOperand(2)); } SDValue DAGTypeLegalizer::PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo) { @@ -844,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; @@ -1055,18 +1189,54 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N, SDValue LHSL, LHSH, RHSL, RHSH; GetExpandedInteger(N->getOperand(0), LHSL, LHSH); GetExpandedInteger(N->getOperand(1), RHSL, RHSH); - SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); + + MVT NVT = LHSL.getValueType(); + SDVTList VTList = DAG.getVTList(NVT, MVT::Flag); SDValue LoOps[2] = { LHSL, RHSL }; SDValue HiOps[3] = { LHSH, RHSH }; - if (N->getOpcode() == ISD::ADD) { - Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); - HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); + // Do not generate ADDC/ADDE or SUBC/SUBE if the target does not support + // them. TODO: Teach operation legalization how to expand unsupported + // ADDC/ADDE/SUBC/SUBE. The problem is that these operations generate + // a carry of type MVT::Flag, but there doesn't seem to be any way to + // generate a value of this type in the expanded code sequence. + bool hasCarry = + TLI.isOperationLegal(N->getOpcode() == ISD::ADD ? ISD::ADDC : ISD::SUBC, + TLI.getTypeToExpandTo(NVT)); + + if (hasCarry) { + if (N->getOpcode() == ISD::ADD) { + Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); + HiOps[2] = Lo.getValue(1); + Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); + } else { + Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2); + HiOps[2] = Lo.getValue(1); + Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3); + } } else { - Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2); - HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3); + if (N->getOpcode() == ISD::ADD) { + Lo = DAG.getNode(ISD::ADD, VTList, LoOps, 2); + Hi = DAG.getNode(ISD::ADD, VTList, HiOps, 2); + SDValue Cmp1 = DAG.getSetCC(TLI.getSetCCResultType(Lo), Lo, LoOps[0], + ISD::SETULT); + SDValue Carry1 = DAG.getNode(ISD::SELECT, NVT, Cmp1, + DAG.getConstant(1, NVT), + DAG.getConstant(0, NVT)); + SDValue Cmp2 = DAG.getSetCC(TLI.getSetCCResultType(Lo), Lo, LoOps[1], + ISD::SETULT); + SDValue Carry2 = DAG.getNode(ISD::SELECT, NVT, Cmp2, + DAG.getConstant(1, NVT), Carry1); + Hi = DAG.getNode(ISD::ADD, NVT, Hi, Carry2); + } else { + Lo = DAG.getNode(ISD::SUB, VTList, LoOps, 2); + Hi = DAG.getNode(ISD::SUB, VTList, HiOps, 2); + SDValue Cmp = DAG.getSetCC(NVT, LoOps[0], LoOps[1], ISD::SETULT); + SDValue Borrow = DAG.getNode(ISD::SELECT, NVT, Cmp, + DAG.getConstant(1, NVT), + DAG.getConstant(0, NVT)); + Hi = DAG.getNode(ISD::SUB, NVT, Hi, Borrow); + } } } @@ -1195,7 +1365,7 @@ void DAGTypeLegalizer::ExpandIntRes_CTLZ(SDNode *N, MVT NVT = Lo.getValueType(); SDValue HiNotZero = DAG.getSetCC(TLI.getSetCCResultType(Hi), Hi, - DAG.getConstant(0, NVT), ISD::SETNE); + DAG.getConstant(0, NVT), ISD::SETNE); SDValue LoLZ = DAG.getNode(ISD::CTLZ, NVT, Lo); SDValue HiLZ = DAG.getNode(ISD::CTLZ, NVT, Hi); @@ -1223,7 +1393,7 @@ void DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N, MVT NVT = Lo.getValueType(); SDValue LoNotZero = DAG.getSetCC(TLI.getSetCCResultType(Lo), Lo, - DAG.getConstant(0, NVT), ISD::SETNE); + DAG.getConstant(0, NVT), ISD::SETNE); SDValue LoLZ = DAG.getNode(ISD::CTTZ, NVT, Lo); SDValue HiLZ = DAG.getNode(ISD::CTTZ, NVT, Hi); @@ -1556,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(); @@ -1670,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 { @@ -1704,7 +1874,7 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) { if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) == TargetLowering::Custom) - Res = TLI.LowerOperation(SDValue(N, OpNo), DAG); + Res = TLI.LowerOperation(SDValue(N, 0), DAG); if (Res.getNode() == 0) { switch (N->getOpcode()) { @@ -2029,25 +2199,29 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) { SDValue Lo, Hi; GetExpandedInteger(Op, Lo, Hi); SDValue SignSet = DAG.getSetCC(TLI.getSetCCResultType(Hi), Hi, - DAG.getConstant(0, Hi.getValueType()), - ISD::SETLT); + DAG.getConstant(0, Hi.getValueType()), + ISD::SETLT); // Build a 64 bit pair (0, FF) in the constant pool, with FF in the lo bits. SDValue FudgePtr = DAG.getConstantPool(ConstantInt::get(FF.zext(64)), - TLI.getPointerTy()); + TLI.getPointerTy()); // Get a pointer to FF if the sign bit was set, or to 0 otherwise. SDValue Zero = DAG.getIntPtrConstant(0); SDValue Four = DAG.getIntPtrConstant(4); if (TLI.isBigEndian()) std::swap(Zero, Four); SDValue Offset = DAG.getNode(ISD::SELECT, Zero.getValueType(), SignSet, - Zero, Four); + Zero, Four); + unsigned Alignment = + 1 << cast(FudgePtr)->getAlignment(); FudgePtr = DAG.getNode(ISD::ADD, TLI.getPointerTy(), FudgePtr, Offset); + Alignment = std::min(Alignment, 4u); // Load the value out, extending it from f32 to the destination float type. // FIXME: Avoid the extend by constructing the right constant pool? SDValue Fudge = DAG.getExtLoad(ISD::EXTLOAD, DstVT, DAG.getEntryNode(), - FudgePtr, NULL, 0, MVT::f32); + FudgePtr, NULL, 0, MVT::f32, + false, Alignment); return DAG.getNode(ISD::FADD, DstVT, SignedConv, Fudge); }