X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FLegalizeDAG.cpp;h=b7fa207895c557c02e9924666144f89d1b01c73e;hp=1ad8e80258549fb6012588437b5a221f6ba8e77f;hb=4ee451de366474b9c228b4e5fa573795a715216d;hpb=5c0d6ed325417baa5d119af9c2b6790231d8565f diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 1ad8e802585..b7fa207895c 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -23,9 +23,9 @@ #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -#include "llvm/Support/MathExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/MathExtras.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallPtrSet.h" @@ -602,6 +602,7 @@ SDOperand ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, ST->isVolatile(), Alignment); Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, DAG.getConstant(IncrementSize, TLI.getPointerTy())); + Alignment = MinAlign(Alignment, IncrementSize); Store2 = DAG.getTruncStore(Chain, TLI.isLittleEndian()?Hi:Lo, Ptr, ST->getSrcValue(), SVOffset + IncrementSize, NewStoredVT, ST->isVolatile(), Alignment); @@ -618,13 +619,13 @@ SDOperand ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, SDOperand Ptr = LD->getBasePtr(); MVT::ValueType VT = LD->getValueType(0); MVT::ValueType LoadedVT = LD->getLoadedVT(); - if (MVT::isFloatingPoint(VT)) { + if (MVT::isFloatingPoint(VT) && !MVT::isVector(VT)) { // Expand to a (misaligned) integer load of the same size, // then bitconvert to floating point. MVT::ValueType intVT; - if (LoadedVT==MVT::f64) + if (LoadedVT == MVT::f64) intVT = MVT::i64; - else if (LoadedVT==MVT::f32) + else if (LoadedVT == MVT::f32) intVT = MVT::i32; else assert(0 && "Unaligned load of unsupported floating point type"); @@ -640,11 +641,25 @@ SDOperand ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, return DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(VT, MVT::Other), Ops, 2); } - assert(MVT::isInteger(LoadedVT) && "Unaligned load of unsupported type."); - MVT::ValueType NewLoadedVT = LoadedVT - 1; - int NumBits = MVT::getSizeInBits(NewLoadedVT); - int Alignment = LD->getAlignment(); - int IncrementSize = NumBits / 8; + assert((MVT::isInteger(LoadedVT) || MVT::isVector(LoadedVT)) && + "Unaligned load of unsupported type."); + + // Compute the new VT that is half the size of the old one. We either have an + // integer MVT or we have a vector MVT. + unsigned NumBits = MVT::getSizeInBits(LoadedVT); + MVT::ValueType NewLoadedVT; + if (!MVT::isVector(LoadedVT)) { + NewLoadedVT = MVT::getIntegerType(NumBits/2); + } else { + // FIXME: This is not right for <1 x anything> it is also not right for + // non-power-of-two vectors. + NewLoadedVT = MVT::getVectorType(MVT::getVectorElementType(LoadedVT), + MVT::getVectorNumElements(LoadedVT)/2); + } + NumBits >>= 1; + + unsigned Alignment = LD->getAlignment(); + unsigned IncrementSize = NumBits / 8; ISD::LoadExtType HiExtType = LD->getExtensionType(); // If the original load is NON_EXTLOAD, the hi part load must be ZEXTLOAD. @@ -660,7 +675,7 @@ SDOperand ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, DAG.getConstant(IncrementSize, TLI.getPointerTy())); Hi = DAG.getExtLoad(HiExtType, VT, Chain, Ptr, LD->getSrcValue(), SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(), - Alignment); + MinAlign(Alignment, IncrementSize)); } else { Hi = DAG.getExtLoad(HiExtType, VT, Chain, Ptr, LD->getSrcValue(), SVOffset, NewLoadedVT,LD->isVolatile(), Alignment); @@ -668,7 +683,7 @@ SDOperand ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, DAG.getConstant(IncrementSize, TLI.getPointerTy())); Lo = DAG.getExtLoad(ISD::ZEXTLOAD, VT, Chain, Ptr, LD->getSrcValue(), SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(), - Alignment); + MinAlign(Alignment, IncrementSize)); } // aggregate the two parts @@ -1141,12 +1156,20 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { // The only option for this is to custom lower it. Tmp3 = TLI.LowerOperation(Result.getValue(0), DAG); assert(Tmp3.Val && "Target didn't custom lower this node!"); - assert(Tmp3.Val->getNumValues() == Result.Val->getNumValues() && + + // The number of incoming and outgoing values should match; unless the final + // outgoing value is a flag. + assert((Tmp3.Val->getNumValues() == Result.Val->getNumValues() || + (Tmp3.Val->getNumValues() == Result.Val->getNumValues() + 1 && + Tmp3.Val->getValueType(Tmp3.Val->getNumValues() - 1) == + MVT::Flag)) && "Lowering call/formal_arguments produced unexpected # results!"); // Since CALL/FORMAL_ARGUMENTS nodes produce multiple values, make sure to // remember that we legalized all of them, so it doesn't get relegalized. for (unsigned i = 0, e = Tmp3.Val->getNumValues(); i != e; ++i) { + if (Tmp3.Val->getValueType(i) == MVT::Flag) + continue; Tmp1 = LegalizeOp(Tmp3.getValue(i)); if (Op.ResNo == i) Tmp2 = Tmp1; @@ -1471,6 +1494,12 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { assert(SPReg && "Target cannot require DYNAMIC_STACKALLOC expansion and" " not tell us which reg is the stack pointer!"); SDOperand Chain = Tmp1.getOperand(0); + + // Chain the dynamic stack allocation so that it doesn't modify the stack + // pointer when other instructions are using the stack. + Chain = DAG.getCALLSEQ_START(Chain, + DAG.getConstant(0, TLI.getPointerTy())); + SDOperand Size = Tmp2.getOperand(1); SDOperand SP = DAG.getCopyFromReg(Chain, SPReg, VT); Chain = SP.getValue(1); @@ -1481,7 +1510,14 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { SP = DAG.getNode(ISD::AND, VT, SP, DAG.getConstant(-(uint64_t)Align, VT)); Tmp1 = DAG.getNode(ISD::SUB, VT, SP, Size); // Value - Tmp2 = DAG.getCopyToReg(Chain, SPReg, Tmp1); // Output chain + Chain = DAG.getCopyToReg(Chain, SPReg, Tmp1); // Output chain + + Tmp2 = + DAG.getCALLSEQ_END(Chain, + DAG.getConstant(0, TLI.getPointerTy()), + DAG.getConstant(0, TLI.getPointerTy()), + SDOperand()); + Tmp1 = LegalizeOp(Tmp1); Tmp2 = LegalizeOp(Tmp2); break; @@ -1597,21 +1633,17 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case 8: LD = DAG.getLoad(MVT::i64, Chain, Addr, NULL, 0); break; } + Addr = LD; if (TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_) { // For PIC, the sequence is: // BRIND(load(Jumptable + index) + RelocBase) - // RelocBase is the JumpTable on PPC and X86, GOT on Alpha - SDOperand Reloc; - if (TLI.usesGlobalOffsetTable()) - Reloc = DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, PTy); - else - Reloc = Table; - Addr = (PTy != MVT::i32) ? DAG.getNode(ISD::SIGN_EXTEND, PTy, LD) : LD; - Addr = DAG.getNode(ISD::ADD, PTy, Addr, Reloc); - Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), Addr); - } else { - Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), LD); + // RelocBase can be JumpTable, GOT or some sort of global base. + if (PTy != MVT::i32) + Addr = DAG.getNode(ISD::SIGN_EXTEND, PTy, Addr); + Addr = DAG.getNode(ISD::ADD, PTy, Addr, + TLI.getPICJumpTableRelocBase(Table, DAG)); } + Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), Addr); } } break; @@ -1919,8 +1951,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Result = LegalizeOp(Result); } else { SDNode *InVal = Tmp2.Val; - unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0)); - MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0)); + int InIx = Tmp2.ResNo; + unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(InIx)); + MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(InIx)); // Figure out if there is a simple type corresponding to this Vector // type. If so, convert to the vector type. @@ -2054,7 +2087,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2, getIntPtrConstant(4)); Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset+4, - isVolatile, std::max(Alignment, 4U)); + isVolatile, MinAlign(Alignment, 4U)); Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); break; @@ -2114,8 +2147,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { // in the high half of the vector. if (MVT::isVector(ST->getValue().getValueType())) { SDNode *InVal = ST->getValue().Val; - unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0)); - MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0)); + int InIx = ST->getValue().ResNo; + unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(InIx)); + MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(InIx)); // Figure out if there is a simple type corresponding to this Vector // type. If so, convert to the vector type. @@ -2138,7 +2172,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { break; } else { SplitVectorOp(Node->getOperand(1), Lo, Hi); - IncrementSize = NumElems/2 * MVT::getSizeInBits(EVT)/8; + IncrementSize = MVT::getVectorNumElements(Lo.Val->getValueType(0)) * + MVT::getSizeInBits(EVT)/8; } } else { ExpandOp(Node->getOperand(1), Lo, Hi); @@ -2162,8 +2197,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { assert(isTypeLegal(Tmp2.getValueType()) && "Pointers must be legal!"); SVOffset += IncrementSize; - if (Alignment > IncrementSize) - Alignment = IncrementSize; + Alignment = MinAlign(Alignment, IncrementSize); Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset, isVolatile, Alignment); Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); @@ -2922,6 +2956,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Result = DAG.getNode(DivOpc, VT, Tmp1, Tmp2); Result = DAG.getNode(ISD::MUL, VT, Result, Tmp2); Result = DAG.getNode(ISD::SUB, VT, Tmp1, Result); + } else if (MVT::isVector(VT)) { + Result = LegalizeOp(UnrollVectorOp(Op)); } else { assert(VT == MVT::i32 && "Cannot expand this binary operator!"); @@ -2931,12 +2967,18 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Result = ExpandLibCall(TLI.getLibcallName(LC), Node, isSigned, Dummy); } } else { - // Floating point mod -> fmod libcall. - RTLIB::Libcall LC = VT == MVT::f32 - ? RTLIB::REM_F32 : RTLIB::REM_F64; - SDOperand Dummy; - Result = ExpandLibCall(TLI.getLibcallName(LC), Node, - false/*sign irrelevant*/, Dummy); + assert(MVT::isFloatingPoint(VT) && + "remainder op must have integer or floating-point type"); + if (MVT::isVector(VT)) { + Result = LegalizeOp(UnrollVectorOp(Op)); + } else { + // Floating point mod -> fmod libcall. + RTLIB::Libcall LC = VT == MVT::f32 + ? RTLIB::REM_F32 : RTLIB::REM_F64; + SDOperand Dummy; + Result = ExpandLibCall(TLI.getLibcallName(LC), Node, + false/*sign irrelevant*/, Dummy); + } } break; } @@ -3260,8 +3302,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { // The input has to be a vector type, we have to either scalarize it, pack // it, or convert it based on whether the input vector type is legal. SDNode *InVal = Node->getOperand(0).Val; - unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0)); - MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0)); + int InIx = Node->getOperand(0).ResNo; + unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(InIx)); + MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(InIx)); // Figure out if there is a simple type corresponding to this Vector // type. If so, convert to the vector type. @@ -3520,7 +3563,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { MVT::ValueType slotVT = (Node->getOpcode() == ISD::FP_EXTEND) ? oldVT : newVT; const Type *Ty = MVT::getTypeForValueType(slotVT); - uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty); + uint64_t TySize = TLI.getTargetData()->getABITypeSize(Ty); unsigned Align = TLI.getTargetData()->getPrefTypeAlignment(Ty); MachineFunction &MF = DAG.getMachineFunction(); int SSFI = @@ -3614,7 +3657,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { // slots and always reusing the same one. We currently always create // new ones, as reuse may inhibit scheduling. const Type *Ty = MVT::getTypeForValueType(ExtraVT); - uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty); + uint64_t TySize = TLI.getTargetData()->getABITypeSize(Ty); unsigned Align = TLI.getTargetData()->getPrefTypeAlignment(Ty); MachineFunction &MF = DAG.getMachineFunction(); int SSFI = @@ -3647,6 +3690,20 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { AddLegalizedOperand(SDOperand(Node, 0), Result); AddLegalizedOperand(SDOperand(Node, 1), Tmp1); return Op.ResNo ? Tmp1 : Result; + } + case ISD::FLT_ROUNDS: { + MVT::ValueType VT = Node->getValueType(0); + switch (TLI.getOperationAction(Node->getOpcode(), VT)) { + default: assert(0 && "This action not supported for this op yet!"); + case TargetLowering::Custom: + Result = TLI.LowerOperation(Op, DAG); + if (Result.Val) break; + // Fall Thru + case TargetLowering::Legal: + // If this operation is not supported, lower it to constant 1 + Result = DAG.getConstant(1, VT); + break; + } } } @@ -4150,9 +4207,9 @@ SDOperand SelectionDAGLegalize::ExpandEXTRACT_VECTOR_ELT(SDOperand Op) { if (MVT::getSizeInBits(Idx.getValueType()) > MVT::getSizeInBits(TLI.getPointerTy())) - Idx = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), StackPtr); + Idx = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), Idx); else - Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), StackPtr); + Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx); StackPtr = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, StackPtr); @@ -5130,10 +5187,21 @@ SDOperand SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDOperand LegalOp, // Otherwise, try a larger type. } - // Okay, we found the operation and type to use. Truncate the result of the - // extended FP_TO_*INT operation to the desired size. - return DAG.getNode(ISD::TRUNCATE, DestVT, - DAG.getNode(OpToUse, NewOutTy, LegalOp)); + + // Okay, we found the operation and type to use. + SDOperand Operation = DAG.getNode(OpToUse, NewOutTy, LegalOp); + + // If the operation produces an invalid type, it must be custom lowered. Use + // the target lowering hooks to expand it. Just keep the low part of the + // expanded operation, we know that we're truncating anyway. + if (getTypeAction(NewOutTy) == Expand) { + Operation = SDOperand(TLI.ExpandOperationResult(Operation.Val, DAG), 0); + assert(Operation.Val && "Didn't return anything"); + } + + // Truncate the result of the extended FP_TO_*INT operation to the desired + // size. + return DAG.getNode(ISD::TRUNCATE, DestVT, Operation); } /// ExpandBSWAP - Open code the operations for BSWAP of the specified operation. @@ -5295,6 +5363,11 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ #endif assert(0 && "Do not know how to expand this operator!"); abort(); + case ISD::EXTRACT_VECTOR_ELT: + assert(VT==MVT::i64 && "Do not know how to expand this operator!"); + // ExpandEXTRACT_VECTOR_ELT tolerates invalid result types. + Lo = ExpandEXTRACT_VECTOR_ELT(Op); + return ExpandOp(Lo, Lo, Hi); case ISD::UNDEF: NVT = TLI.getTypeToExpandTo(VT); Lo = DAG.getNode(ISD::UNDEF, NVT); @@ -5326,6 +5399,20 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ Lo = Node->getOperand(0); Hi = Node->getOperand(1); break; + + case ISD::MERGE_VALUES: + if (Node->getNumValues() == 1) { + ExpandOp(Op.getOperand(0), Lo, Hi); + break; + } + // FIXME: For now only expand i64,chain = MERGE_VALUES (x, y) + assert(Op.ResNo == 0 && Node->getNumValues() == 2 && + Op.getValue(1).getValueType() == MVT::Other && + "unhandled MERGE_VALUES"); + ExpandOp(Op.getOperand(0), Lo, Hi); + // Remember that we legalized the chain. + AddLegalizedOperand(Op.getValue(1), LegalizeOp(Op.getOperand(1))); + break; case ISD::SIGN_EXTEND_INREG: ExpandOp(Node->getOperand(0), Lo, Hi); @@ -5426,8 +5513,7 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, getIntPtrConstant(IncrementSize)); SVOffset += IncrementSize; - if (Alignment > IncrementSize) - Alignment = IncrementSize; + Alignment = MinAlign(Alignment, IncrementSize); Hi = DAG.getLoad(NVT, Ch, Ptr, LD->getSrcValue(), SVOffset, isVolatile, Alignment); @@ -5443,7 +5529,8 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ } else { MVT::ValueType EVT = LD->getLoadedVT(); - if (VT == MVT::f64 && EVT == MVT::f32) { + if ((VT == MVT::f64 && EVT == MVT::f32) || + (VT == MVT::ppcf128 && (EVT==MVT::f64 || EVT==MVT::f32))) { // f64 = EXTLOAD f32 should expand to LOAD, FP_EXTEND SDOperand Load = DAG.getLoad(EVT, Ch, Ptr, LD->getSrcValue(), SVOffset, isVolatile, Alignment); @@ -5590,16 +5677,17 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ break; } - case ISD::READCYCLECOUNTER: + case ISD::READCYCLECOUNTER: { assert(TLI.getOperationAction(ISD::READCYCLECOUNTER, VT) == TargetLowering::Custom && "Must custom expand ReadCycleCounter"); - Lo = TLI.LowerOperation(Op, DAG); - assert(Lo.Val && "Node must be custom expanded!"); - Hi = Lo.getValue(1); + SDOperand Tmp = TLI.LowerOperation(Op, DAG); + assert(Tmp.Val && "Node must be custom expanded!"); + ExpandOp(Tmp.getValue(0), Lo, Hi); AddLegalizedOperand(SDOperand(Node, 1), // Remember we legalized the chain. - LegalizeOp(Lo.getValue(2))); + LegalizeOp(Tmp.getValue(1))); break; + } // These operators cannot be expanded directly, emit them as calls to // library functions. @@ -5926,6 +6014,15 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); break; } + if (HasMULHU) { + Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); + Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); + RH = DAG.getNode(ISD::MUL, NVT, LL, RH); + LH = DAG.getNode(ISD::MUL, NVT, LH, RL); + Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH); + Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); + break; + } } // If nothing else, we can make a libcall. @@ -6184,10 +6281,15 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo, SDNode *Node = Op.Val; unsigned NumElements = MVT::getVectorNumElements(Op.getValueType()); assert(NumElements > 1 && "Cannot split a single element vector!"); - unsigned NewNumElts = NumElements/2; + MVT::ValueType NewEltVT = MVT::getVectorElementType(Op.getValueType()); - MVT::ValueType NewVT = MVT::getVectorType(NewEltVT, NewNumElts); - + + unsigned NewNumElts_Lo = 1 << Log2_32(NumElements-1); + unsigned NewNumElts_Hi = NumElements - NewNumElts_Lo; + + MVT::ValueType NewVT_Lo = MVT::getVectorType(NewEltVT, NewNumElts_Lo); + MVT::ValueType NewVT_Hi = MVT::getVectorType(NewEltVT, NewNumElts_Hi); + // See if we already split it. std::map >::iterator I = SplitNodes.find(Op); @@ -6203,6 +6305,10 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo, Node->dump(&DAG); #endif assert(0 && "Unhandled operation in SplitVectorOp!"); + case ISD::UNDEF: + Lo = DAG.getNode(ISD::UNDEF, NewVT_Lo); + Hi = DAG.getNode(ISD::UNDEF, NewVT_Hi); + break; case ISD::BUILD_PAIR: Lo = Node->getOperand(0); Hi = Node->getOperand(1); @@ -6211,25 +6317,62 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo, SplitVectorOp(Node->getOperand(0), Lo, Hi); unsigned Index = cast(Node->getOperand(2))->getValue(); SDOperand ScalarOp = Node->getOperand(1); - if (Index < NewNumElts) - Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT, Lo, ScalarOp, + if (Index < NewNumElts_Lo) + Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Lo, Lo, ScalarOp, DAG.getConstant(Index, TLI.getPointerTy())); else - Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT, Hi, ScalarOp, - DAG.getConstant(Index - NewNumElts, TLI.getPointerTy())); + Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Hi, Hi, ScalarOp, + DAG.getConstant(Index - NewNumElts_Lo, + TLI.getPointerTy())); + break; + } + case ISD::VECTOR_SHUFFLE: { + // Build the low part. + SDOperand Mask = Node->getOperand(2); + SmallVector Ops; + MVT::ValueType PtrVT = TLI.getPointerTy(); + + // Insert all of the elements from the input that are needed. We use + // buildvector of extractelement here because the input vectors will have + // to be legalized, so this makes the code simpler. + for (unsigned i = 0; i != NewNumElts_Lo; ++i) { + unsigned Idx = cast(Mask.getOperand(i))->getValue(); + SDOperand InVec = Node->getOperand(0); + if (Idx >= NumElements) { + InVec = Node->getOperand(1); + Idx -= NumElements; + } + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, InVec, + DAG.getConstant(Idx, PtrVT))); + } + Lo = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Lo, &Ops[0], Ops.size()); + Ops.clear(); + + for (unsigned i = NewNumElts_Lo; i != NumElements; ++i) { + unsigned Idx = cast(Mask.getOperand(i))->getValue(); + SDOperand InVec = Node->getOperand(0); + if (Idx >= NumElements) { + InVec = Node->getOperand(1); + Idx -= NumElements; + } + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, InVec, + DAG.getConstant(Idx, PtrVT))); + } + Hi = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Lo, &Ops[0], Ops.size()); break; } case ISD::BUILD_VECTOR: { SmallVector LoOps(Node->op_begin(), - Node->op_begin()+NewNumElts); - Lo = DAG.getNode(ISD::BUILD_VECTOR, NewVT, &LoOps[0], LoOps.size()); + Node->op_begin()+NewNumElts_Lo); + Lo = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Lo, &LoOps[0], LoOps.size()); - SmallVector HiOps(Node->op_begin()+NewNumElts, + SmallVector HiOps(Node->op_begin()+NewNumElts_Lo, Node->op_end()); - Hi = DAG.getNode(ISD::BUILD_VECTOR, NewVT, &HiOps[0], HiOps.size()); + Hi = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Hi, &HiOps[0], HiOps.size()); break; } case ISD::CONCAT_VECTORS: { + // FIXME: Handle non-power-of-two vectors? unsigned NewNumSubvectors = Node->getNumOperands() / 2; if (NewNumSubvectors == 1) { Lo = Node->getOperand(0); @@ -6237,11 +6380,11 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo, } else { SmallVector LoOps(Node->op_begin(), Node->op_begin()+NewNumSubvectors); - Lo = DAG.getNode(ISD::CONCAT_VECTORS, NewVT, &LoOps[0], LoOps.size()); + Lo = DAG.getNode(ISD::CONCAT_VECTORS, NewVT_Lo, &LoOps[0], LoOps.size()); SmallVector HiOps(Node->op_begin()+NewNumSubvectors, Node->op_end()); - Hi = DAG.getNode(ISD::CONCAT_VECTORS, NewVT, &HiOps[0], HiOps.size()); + Hi = DAG.getNode(ISD::CONCAT_VECTORS, NewVT_Hi, &HiOps[0], HiOps.size()); } break; } @@ -6256,12 +6399,12 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo, // Handle a vector merge. SDOperand CL, CH; SplitVectorOp(Cond, CL, CH); - Lo = DAG.getNode(Node->getOpcode(), NewVT, CL, LL, RL); - Hi = DAG.getNode(Node->getOpcode(), NewVT, CH, LH, RH); + Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, CL, LL, RL); + Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, CH, LH, RH); } else { // Handle a simple select with vector operands. - Lo = DAG.getNode(Node->getOpcode(), NewVT, Cond, LL, RL); - Hi = DAG.getNode(Node->getOpcode(), NewVT, Cond, LH, RH); + Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, Cond, LL, RL); + Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, Cond, LH, RH); } break; } @@ -6277,21 +6420,24 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo, case ISD::FPOW: case ISD::AND: case ISD::OR: - case ISD::XOR: { + case ISD::XOR: + case ISD::UREM: + case ISD::SREM: + case ISD::FREM: { SDOperand LL, LH, RL, RH; SplitVectorOp(Node->getOperand(0), LL, LH); SplitVectorOp(Node->getOperand(1), RL, RH); - Lo = DAG.getNode(Node->getOpcode(), NewVT, LL, RL); - Hi = DAG.getNode(Node->getOpcode(), NewVT, LH, RH); + Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, LL, RL); + Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, LH, RH); break; } case ISD::FPOWI: { SDOperand L, H; SplitVectorOp(Node->getOperand(0), L, H); - Lo = DAG.getNode(Node->getOpcode(), NewVT, L, Node->getOperand(1)); - Hi = DAG.getNode(Node->getOpcode(), NewVT, H, Node->getOperand(1)); + Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, L, Node->getOperand(1)); + Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, H, Node->getOperand(1)); break; } case ISD::CTTZ: @@ -6301,12 +6447,16 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo, case ISD::FABS: case ISD::FSQRT: case ISD::FSIN: - case ISD::FCOS: { + case ISD::FCOS: + case ISD::FP_TO_SINT: + case ISD::FP_TO_UINT: + case ISD::SINT_TO_FP: + case ISD::UINT_TO_FP: { SDOperand L, H; SplitVectorOp(Node->getOperand(0), L, H); - Lo = DAG.getNode(Node->getOpcode(), NewVT, L); - Hi = DAG.getNode(Node->getOpcode(), NewVT, H); + Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, L); + Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, H); break; } case ISD::LOAD: { @@ -6318,14 +6468,13 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo, unsigned Alignment = LD->getAlignment(); bool isVolatile = LD->isVolatile(); - Lo = DAG.getLoad(NewVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment); - unsigned IncrementSize = NewNumElts * MVT::getSizeInBits(NewEltVT)/8; + Lo = DAG.getLoad(NewVT_Lo, Ch, Ptr, SV, SVOffset, isVolatile, Alignment); + unsigned IncrementSize = NewNumElts_Lo * MVT::getSizeInBits(NewEltVT)/8; Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, getIntPtrConstant(IncrementSize)); SVOffset += IncrementSize; - if (Alignment > IncrementSize) - Alignment = IncrementSize; - Hi = DAG.getLoad(NewVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment); + Alignment = MinAlign(Alignment, IncrementSize); + Hi = DAG.getLoad(NewVT_Hi, Ch, Ptr, SV, SVOffset, isVolatile, Alignment); // Build a factor node to remember that this load is independent of the // other one. @@ -6353,8 +6502,8 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo, } // Split the vector and convert each of the pieces now. SplitVectorOp(InOp, Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, NewVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, NewVT, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, NewVT_Lo, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, NewVT_Hi, Hi); break; } }