1 Pull in r211435 from upstream llvm trunk (by Benjamin Kramer):
3 Legalizer: Add support for splitting insert_subvectors.
5 We handle this by spilling the whole thing to the stack and doing the
8 PR19492. This happens in real code because the vectorizer creates
9 v2i128 when AVX is enabled.
11 This fixes a "fatal error: error in backend: Do not know how to split
12 the result of this operator!" message encountered during compilation of
13 the net-p2p/libtorrent-rasterbar port.
15 Introduced here: http://svnweb.freebsd.org/changeset/base/267704
17 Index: 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);
29 Index: 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()));
45 +void DAGTypeLegalizer::SplitVecRes_INSERT_SUBVECTOR(SDNode *N, SDValue &Lo,
47 + SDValue Vec = N->getOperand(0);
48 + SDValue SubVec = N->getOperand(1);
49 + SDValue Idx = N->getOperand(2);
51 + GetSplitVector(Vec, Lo, Hi);
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);
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(),
67 + // Load the Lo part from the stack slot.
68 + Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, MachinePointerInfo(),
69 + false, false, false, 0);
71 + // Increment the pointer to the other part.
72 + unsigned IncrementSize = Lo.getValueType().getSizeInBits() / 8;
74 + DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
75 + DAG.getConstant(IncrementSize, StackPtr.getValueType()));
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));
82 void DAGTypeLegalizer::SplitVecRes_FPOWI(SDNode *N, SDValue &Lo,
85 Index: 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
95 +define i128 @split128(<2 x i128> %a, <2 x i128> %b) {
96 +; SSE4-LABEL: split128:
104 +; AVX1-LABEL: split128:
112 +; AVX2-LABEL: split128:
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