1267705SdimPull in r211435 from upstream llvm trunk (by Benjamin Kramer): 2267705Sdim 3267705Sdim Legalizer: Add support for splitting insert_subvectors. 4267705Sdim 5267705Sdim We handle this by spilling the whole thing to the stack and doing the 6267705Sdim insertion as a store. 7267705Sdim 8267705Sdim PR19492. This happens in real code because the vectorizer creates 9267705Sdim v2i128 when AVX is enabled. 10267705Sdim 11267705SdimThis fixes a "fatal error: error in backend: Do not know how to split 12267705Sdimthe result of this operator!" message encountered during compilation of 13267705Sdimthe net-p2p/libtorrent-rasterbar port. 14267705Sdim 15267705SdimIntroduced here: http://svnweb.freebsd.org/changeset/base/267704 16267705Sdim 17267705SdimIndex: lib/CodeGen/SelectionDAG/LegalizeTypes.h 18267705Sdim=================================================================== 19267705Sdim--- lib/CodeGen/SelectionDAG/LegalizeTypes.h 20267705Sdim+++ lib/CodeGen/SelectionDAG/LegalizeTypes.h 21267705Sdim@@ -569,6 +569,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { 22267705Sdim void SplitVecRes_BUILD_VECTOR(SDNode *N, SDValue &Lo, SDValue &Hi); 23267705Sdim void SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo, SDValue &Hi); 24267705Sdim void SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo, SDValue &Hi); 25267705Sdim+ void SplitVecRes_INSERT_SUBVECTOR(SDNode *N, SDValue &Lo, SDValue &Hi); 26267705Sdim void SplitVecRes_FPOWI(SDNode *N, SDValue &Lo, SDValue &Hi); 27267705Sdim void SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, SDValue &Hi); 28267705Sdim void SplitVecRes_LOAD(LoadSDNode *N, SDValue &Lo, SDValue &Hi); 29267705SdimIndex: lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp 30267705Sdim=================================================================== 31267705Sdim--- lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp 32267705Sdim+++ lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp 33267705Sdim@@ -506,6 +506,7 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N 34267705Sdim case ISD::BUILD_VECTOR: SplitVecRes_BUILD_VECTOR(N, Lo, Hi); break; 35267705Sdim case ISD::CONCAT_VECTORS: SplitVecRes_CONCAT_VECTORS(N, Lo, Hi); break; 36267705Sdim case ISD::EXTRACT_SUBVECTOR: SplitVecRes_EXTRACT_SUBVECTOR(N, Lo, Hi); break; 37267705Sdim+ case ISD::INSERT_SUBVECTOR: SplitVecRes_INSERT_SUBVECTOR(N, Lo, Hi); break; 38267705Sdim case ISD::FP_ROUND_INREG: SplitVecRes_InregOp(N, Lo, Hi); break; 39267705Sdim case ISD::FPOWI: SplitVecRes_FPOWI(N, Lo, Hi); break; 40267705Sdim case ISD::INSERT_VECTOR_ELT: SplitVecRes_INSERT_VECTOR_ELT(N, Lo, Hi); break; 41267705Sdim@@ -725,6 +726,43 @@ void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECT 42267705Sdim TLI.getVectorIdxTy())); 43267705Sdim } 44267705Sdim 45267705Sdim+void DAGTypeLegalizer::SplitVecRes_INSERT_SUBVECTOR(SDNode *N, SDValue &Lo, 46267705Sdim+ SDValue &Hi) { 47267705Sdim+ SDValue Vec = N->getOperand(0); 48267705Sdim+ SDValue SubVec = N->getOperand(1); 49267705Sdim+ SDValue Idx = N->getOperand(2); 50267705Sdim+ SDLoc dl(N); 51267705Sdim+ GetSplitVector(Vec, Lo, Hi); 52267705Sdim+ 53267705Sdim+ // Spill the vector to the stack. 54267705Sdim+ EVT VecVT = Vec.getValueType(); 55267705Sdim+ EVT SubVecVT = VecVT.getVectorElementType(); 56267705Sdim+ SDValue StackPtr = DAG.CreateStackTemporary(VecVT); 57267705Sdim+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, 58267705Sdim+ MachinePointerInfo(), false, false, 0); 59267705Sdim+ 60267705Sdim+ // Store the new subvector into the specified index. 61267705Sdim+ SDValue SubVecPtr = GetVectorElementPointer(StackPtr, SubVecVT, Idx); 62267705Sdim+ Type *VecType = VecVT.getTypeForEVT(*DAG.getContext()); 63267705Sdim+ unsigned Alignment = TLI.getDataLayout()->getPrefTypeAlignment(VecType); 64267705Sdim+ Store = DAG.getStore(Store, dl, SubVec, SubVecPtr, MachinePointerInfo(), 65267705Sdim+ false, false, 0); 66267705Sdim+ 67267705Sdim+ // Load the Lo part from the stack slot. 68267705Sdim+ Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, MachinePointerInfo(), 69267705Sdim+ false, false, false, 0); 70267705Sdim+ 71267705Sdim+ // Increment the pointer to the other part. 72267705Sdim+ unsigned IncrementSize = Lo.getValueType().getSizeInBits() / 8; 73267705Sdim+ StackPtr = 74267705Sdim+ DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 75267705Sdim+ DAG.getConstant(IncrementSize, StackPtr.getValueType())); 76267705Sdim+ 77267705Sdim+ // Load the Hi part from the stack slot. 78267705Sdim+ Hi = DAG.getLoad(Hi.getValueType(), dl, Store, StackPtr, MachinePointerInfo(), 79267705Sdim+ false, false, false, MinAlign(Alignment, IncrementSize)); 80267705Sdim+} 81267705Sdim+ 82267705Sdim void DAGTypeLegalizer::SplitVecRes_FPOWI(SDNode *N, SDValue &Lo, 83267705Sdim SDValue &Hi) { 84267705Sdim SDLoc dl(N); 85267705SdimIndex: test/CodeGen/X86/vec_split.ll 86267705Sdim=================================================================== 87267705Sdim--- test/CodeGen/X86/vec_split.ll 88267705Sdim+++ test/CodeGen/X86/vec_split.ll 89267705Sdim@@ -40,3 +40,36 @@ define <32 x i16> @split32(<32 x i16> %a, <32 x i1 90267705Sdim %2 = select <32 x i1> %1, <32 x i16> %a, <32 x i16> %b 91267705Sdim ret <32 x i16> %2 92267705Sdim } 93267705Sdim+ 94267705Sdim+; PR19492 95267705Sdim+define i128 @split128(<2 x i128> %a, <2 x i128> %b) { 96267705Sdim+; SSE4-LABEL: split128: 97267705Sdim+; SSE4: addq 98267705Sdim+; SSE4: adcq 99267705Sdim+; SSE4: addq 100267705Sdim+; SSE4: adcq 101267705Sdim+; SSE4: addq 102267705Sdim+; SSE4: adcq 103267705Sdim+; SSE4: ret 104267705Sdim+; AVX1-LABEL: split128: 105267705Sdim+; AVX1: addq 106267705Sdim+; AVX1: adcq 107267705Sdim+; AVX1: addq 108267705Sdim+; AVX1: adcq 109267705Sdim+; AVX1: addq 110267705Sdim+; AVX1: adcq 111267705Sdim+; AVX1: ret 112267705Sdim+; AVX2-LABEL: split128: 113267705Sdim+; AVX2: addq 114267705Sdim+; AVX2: adcq 115267705Sdim+; AVX2: addq 116267705Sdim+; AVX2: adcq 117267705Sdim+; AVX2: addq 118267705Sdim+; AVX2: adcq 119267705Sdim+; AVX2: ret 120267705Sdim+ %add = add nsw <2 x i128> %a, %b 121267705Sdim+ %rdx.shuf = shufflevector <2 x i128> %add, <2 x i128> undef, <2 x i32> <i32 undef, i32 0> 122267705Sdim+ %bin.rdx = add <2 x i128> %add, %rdx.shuf 123267705Sdim+ %e = extractelement <2 x i128> %bin.rdx, i32 1 124267705Sdim+ ret i128 %e 125267705Sdim+} 126