1Pull in r211435 from upstream llvm trunk (by Benjamin Kramer): 2 3 Legalizer: Add support for splitting insert_subvectors. 4 5 We handle this by spilling the whole thing to the stack and doing the 6 insertion as a store. 7 8 PR19492. This happens in real code because the vectorizer creates 9 v2i128 when AVX is enabled. 10 11This fixes a "fatal error: error in backend: Do not know how to split 12the result of this operator!" message encountered during compilation of 13the net-p2p/libtorrent-rasterbar port. 14 15Introduced here: http://svnweb.freebsd.org/changeset/base/267704 16 17Index: lib/CodeGen/SelectionDAG/LegalizeTypes.h 18=================================================================== 19--- lib/CodeGen/SelectionDAG/LegalizeTypes.h 20+++ lib/CodeGen/SelectionDAG/LegalizeTypes.h 21@@ -569,6 +569,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { 22 void SplitVecRes_BUILD_VECTOR(SDNode *N, SDValue &Lo, SDValue &Hi); 23 void SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo, SDValue &Hi); 24 void SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo, SDValue &Hi); 25+ void SplitVecRes_INSERT_SUBVECTOR(SDNode *N, SDValue &Lo, SDValue &Hi); 26 void SplitVecRes_FPOWI(SDNode *N, SDValue &Lo, SDValue &Hi); 27 void SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, SDValue &Hi); 28 void SplitVecRes_LOAD(LoadSDNode *N, SDValue &Lo, SDValue &Hi); 29Index: lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp 30=================================================================== 31--- lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp 32+++ lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp 33@@ -506,6 +506,7 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N 34 case ISD::BUILD_VECTOR: SplitVecRes_BUILD_VECTOR(N, Lo, Hi); break; 35 case ISD::CONCAT_VECTORS: SplitVecRes_CONCAT_VECTORS(N, Lo, Hi); break; 36 case ISD::EXTRACT_SUBVECTOR: SplitVecRes_EXTRACT_SUBVECTOR(N, Lo, Hi); break; 37+ case ISD::INSERT_SUBVECTOR: SplitVecRes_INSERT_SUBVECTOR(N, Lo, Hi); break; 38 case ISD::FP_ROUND_INREG: SplitVecRes_InregOp(N, Lo, Hi); break; 39 case ISD::FPOWI: SplitVecRes_FPOWI(N, Lo, Hi); break; 40 case ISD::INSERT_VECTOR_ELT: SplitVecRes_INSERT_VECTOR_ELT(N, Lo, Hi); break; 41@@ -725,6 +726,43 @@ void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECT 42 TLI.getVectorIdxTy())); 43 } 44 45+void DAGTypeLegalizer::SplitVecRes_INSERT_SUBVECTOR(SDNode *N, SDValue &Lo, 46+ SDValue &Hi) { 47+ SDValue Vec = N->getOperand(0); 48+ SDValue SubVec = N->getOperand(1); 49+ SDValue Idx = N->getOperand(2); 50+ SDLoc dl(N); 51+ GetSplitVector(Vec, Lo, Hi); 52+ 53+ // Spill the vector to the stack. 54+ EVT VecVT = Vec.getValueType(); 55+ EVT SubVecVT = VecVT.getVectorElementType(); 56+ SDValue StackPtr = DAG.CreateStackTemporary(VecVT); 57+ SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, 58+ MachinePointerInfo(), false, false, 0); 59+ 60+ // Store the new subvector into the specified index. 61+ SDValue SubVecPtr = GetVectorElementPointer(StackPtr, SubVecVT, Idx); 62+ Type *VecType = VecVT.getTypeForEVT(*DAG.getContext()); 63+ unsigned Alignment = TLI.getDataLayout()->getPrefTypeAlignment(VecType); 64+ Store = DAG.getStore(Store, dl, SubVec, SubVecPtr, MachinePointerInfo(), 65+ false, false, 0); 66+ 67+ // Load the Lo part from the stack slot. 68+ Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, MachinePointerInfo(), 69+ false, false, false, 0); 70+ 71+ // Increment the pointer to the other part. 72+ unsigned IncrementSize = Lo.getValueType().getSizeInBits() / 8; 73+ StackPtr = 74+ DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 75+ DAG.getConstant(IncrementSize, StackPtr.getValueType())); 76+ 77+ // Load the Hi part from the stack slot. 78+ Hi = DAG.getLoad(Hi.getValueType(), dl, Store, StackPtr, MachinePointerInfo(), 79+ false, false, false, MinAlign(Alignment, IncrementSize)); 80+} 81+ 82 void DAGTypeLegalizer::SplitVecRes_FPOWI(SDNode *N, SDValue &Lo, 83 SDValue &Hi) { 84 SDLoc dl(N); 85Index: test/CodeGen/X86/vec_split.ll 86=================================================================== 87--- test/CodeGen/X86/vec_split.ll 88+++ test/CodeGen/X86/vec_split.ll 89@@ -40,3 +40,36 @@ define <32 x i16> @split32(<32 x i16> %a, <32 x i1 90 %2 = select <32 x i1> %1, <32 x i16> %a, <32 x i16> %b 91 ret <32 x i16> %2 92 } 93+ 94+; PR19492 95+define i128 @split128(<2 x i128> %a, <2 x i128> %b) { 96+; SSE4-LABEL: split128: 97+; SSE4: addq 98+; SSE4: adcq 99+; SSE4: addq 100+; SSE4: adcq 101+; SSE4: addq 102+; SSE4: adcq 103+; SSE4: ret 104+; AVX1-LABEL: split128: 105+; AVX1: addq 106+; AVX1: adcq 107+; AVX1: addq 108+; AVX1: adcq 109+; AVX1: addq 110+; AVX1: adcq 111+; AVX1: ret 112+; AVX2-LABEL: split128: 113+; AVX2: addq 114+; AVX2: adcq 115+; AVX2: addq 116+; AVX2: adcq 117+; AVX2: addq 118+; AVX2: adcq 119+; AVX2: ret 120+ %add = add nsw <2 x i128> %a, %b 121+ %rdx.shuf = shufflevector <2 x i128> %add, <2 x i128> undef, <2 x i32> <i32 undef, i32 0> 122+ %bin.rdx = add <2 x i128> %add, %rdx.shuf 123+ %e = extractelement <2 x i128> %bin.rdx, i32 1 124+ ret i128 %e 125+} 126