llvm.org GIT mirror llvm / d290fa6
[X86] Improve buildFromShuffleMostly for AVX For a 256-bit BUILD_VECTOR consisting mostly of shuffles of 256-bit vectors, both the BUILD_VECTOR and its operands may need to be legalized in multiple steps. Consider: (v8f32 (BUILD_VECTOR (extract_vector_elt (v8f32 %vreg0,) Constant<1>), (extract_vector_elt %vreg0, Constant<2>), (extract_vector_elt %vreg0, Constant<3>), (extract_vector_elt %vreg0, Constant<4>), (extract_vector_elt %vreg0, Constant<5>), (extract_vector_elt %vreg0, Constant<6>), (extract_vector_elt %vreg0, Constant<7>), %vreg1)) a. We can't build a 256-bit vector efficiently so, we need to split it into two 128-bit vecs and combine them with VINSERTX128. b. Operands like (extract_vector_elt (v8f32 %vreg0), Constant<7>) needs to be split into a VEXTRACTX128 and a further extract_vector_elt from the resulting 128-bit vector. c. The extract_vector_elt from b. is lowered into a shuffle to the first element and a movss. Depending on the order in which we legalize the BUILD_VECTOR and its operands[1], buildFromShuffleMostly may be faced with: (v4f32 (BUILD_VECTOR (extract_vector_elt (vector_shuffle<1,u,u,u> (extract_subvector %vreg0, Constant<4>), undef), Constant<0>), (extract_vector_elt (vector_shuffle<2,u,u,u> (extract_subvector %vreg0, Constant<4>), undef), Constant<0>), (extract_vector_elt (vector_shuffle<3,u,u,u> (extract_subvector %vreg0, Constant<4>), undef), Constant<0>), %vreg1)) In order to figure out the underlying vector and their identity we need to see through the shuffles. [1] Note that the order in which operations and their operands are legalized is only guaranteed in the first iteration of LegalizeDAG. Fixes <rdar://problem/16296956> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206634 91177308-0d34-0410-b5e6-96231b3b80d8 Adam Nemet 6 years ago
2 changed file(s) with 60 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
57025702 return SDValue();
57035703 }
57045704
5705 /// \brief For an EXTRACT_VECTOR_ELT with a constant index return the real
5706 /// underlying vector and index.
5707 ///
5708 /// Modifies \p ExtractedFromVec to the real vector and returns the real
5709 /// index.
5710 static int getUnderlyingExtractedFromVec(SDValue &ExtractedFromVec,
5711 SDValue ExtIdx) {
5712 int Idx = cast(ExtIdx)->getZExtValue();
5713 if (!isa(ExtractedFromVec))
5714 return Idx;
5715
5716 // For 256-bit vectors, LowerEXTRACT_VECTOR_ELT_SSE4 may have already
5717 // lowered this:
5718 // (extract_vector_elt (v8f32 %vreg1), Constant<6>)
5719 // to:
5720 // (extract_vector_elt (vector_shuffle<2,u,u,u>
5721 // (extract_subvector (v8f32 %vreg0), Constant<4>),
5722 // undef)
5723 // Constant<0>)
5724 // In this case the vector is the extract_subvector expression and the index
5725 // is 2, as specified by the shuffle.
5726 ShuffleVectorSDNode *SVOp = cast(ExtractedFromVec);
5727 SDValue ShuffleVec = SVOp->getOperand(0);
5728 MVT ShuffleVecVT = ShuffleVec.getSimpleValueType();
5729 assert(ShuffleVecVT.getVectorElementType() ==
5730 ExtractedFromVec.getSimpleValueType().getVectorElementType());
5731
5732 int ShuffleIdx = SVOp->getMaskElt(Idx);
5733 if (isUndefOrInRange(ShuffleIdx, 0, ShuffleVecVT.getVectorNumElements())) {
5734 ExtractedFromVec = ShuffleVec;
5735 return ShuffleIdx;
5736 }
5737 return Idx;
5738 }
5739
57055740 static SDValue buildFromShuffleMostly(SDValue Op, SelectionDAG &DAG) {
57065741 MVT VT = Op.getSimpleValueType();
57075742
57355770
57365771 SDValue ExtractedFromVec = Op.getOperand(i).getOperand(0);
57375772 SDValue ExtIdx = Op.getOperand(i).getOperand(1);
5773 // Quit if non-constant index.
5774 if (!isa(ExtIdx))
5775 return SDValue();
5776 int Idx = getUnderlyingExtractedFromVec(ExtractedFromVec, ExtIdx);
57385777
57395778 // Quit if extracted from vector of different type.
57405779 if (ExtractedFromVec.getValueType() != VT)
5741 return SDValue();
5742
5743 // Quit if non-constant index.
5744 if (!isa(ExtIdx))
57455780 return SDValue();
57465781
57475782 if (VecIn1.getNode() == 0)
57535788 // Quit if more than 2 vectors to shuffle
57545789 return SDValue();
57555790 }
5756
5757 unsigned Idx = cast(ExtIdx)->getZExtValue();
57585791
57595792 if (ExtractedFromVec == VecIn1)
57605793 Mask[i] = Idx;
0 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx | FileCheck %s
1
2 ; Use buildFromShuffleMostly which allows this to be generated as two 128-bit
3 ; shuffles and an insert.
4
5 ; This is the (somewhat questionable) LLVM IR that is generated for:
6 ; x8.s0123456 = x8.s1234567; // x8 is a <8 x float> type
7 ; x8.s7 = f; // f is float
8
9
10 define <8 x float> @test1(<8 x float> %a, float %b) {
11 ; CHECK-LABEL: test1:
12 ; CHECK: vinsertps
13 ; CHECK-NOT: vinsertps
14 entry:
15 %shift = shufflevector <8 x float> %a, <8 x float> undef, <7 x i32>
16 %extend = shufflevector <7 x float> %shift, <7 x float> undef, <8 x i32>
17 %insert = insertelement <8 x float> %extend, float %b, i32 7
18
19 ret <8 x float> %insert
20 }