llvm.org GIT mirror llvm / d77c1c4
Implemented special cases for PerformVSELECTCombine. vselects with constant masks, after legalization, will get turned into specialized shuffle_vectors so they can be matched to blend+imm instructions. Fixed some tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209044 91177308-0d34-0410-b5e6-96231b3b80d8 Filipe Cabecinhas 5 years ago
2 changed file(s) with 67 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
1773517735 return std::make_pair(Opc, NeedSplit);
1773617736 }
1773717737
17738 static SDValue
17739 TransformVSELECTtoBlendVECTOR_SHUFFLE(SDNode *N, SelectionDAG &DAG,
17740 const X86Subtarget *Subtarget) {
17741 SDLoc dl(N);
17742 SDValue Cond = N->getOperand(0);
17743 SDValue LHS = N->getOperand(1);
17744 SDValue RHS = N->getOperand(2);
17745
17746 if (Cond.getOpcode() == ISD::SIGN_EXTEND) {
17747 SDValue CondSrc = Cond->getOperand(0);
17748 if (CondSrc->getOpcode() == ISD::SIGN_EXTEND_INREG)
17749 Cond = CondSrc->getOperand(0);
17750 }
17751
17752 MVT VT = N->getSimpleValueType(0);
17753 MVT EltVT = VT.getVectorElementType();
17754 unsigned NumElems = VT.getVectorNumElements();
17755 // There is no blend with immediate in AVX-512.
17756 if (VT.is512BitVector())
17757 return SDValue();
17758
17759 if (!Subtarget->hasSSE41() || EltVT == MVT::i8)
17760 return SDValue();
17761 if (!Subtarget->hasInt256() && VT == MVT::v16i16)
17762 return SDValue();
17763
17764 if (!ISD::isBuildVectorOfConstantSDNodes(Cond.getNode()))
17765 return SDValue();
17766
17767 unsigned MaskValue = 0;
17768 if (!BUILD_VECTORtoBlendMask(cast(Cond), MaskValue))
17769 return SDValue();
17770
17771 SmallVector ShuffleMask(NumElems, -1);
17772 for (unsigned i = 0; i < NumElems; ++i) {
17773 // Be sure we emit undef where we can.
17774 if (Cond.getOperand(i)->getOpcode() == ISD::UNDEF)
17775 ShuffleMask[i] = -1;
17776 else
17777 ShuffleMask[i] = i + NumElems * ((MaskValue >> i) & 1);
17778 }
17779
17780 return DAG.getVectorShuffle(VT, dl, LHS, RHS, &ShuffleMask[0]);
17781 }
17782
1773817783 /// PerformSELECTCombine - Do target-specific dag combines on SELECT and VSELECT
1773917784 /// nodes.
1774017785 static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
1827418319 if (TLO.ShrinkDemandedConstant(Cond, DemandedMask) ||
1827518320 TLI.SimplifyDemandedBits(Cond, DemandedMask, KnownZero, KnownOne, TLO))
1827618321 DCI.CommitTargetLoweringOpt(TLO);
18322 }
18323
18324 // We should generate an X86ISD::BLENDI from a vselect if its argument
18325 // is a sign_extend_inreg of an any_extend of a BUILD_VECTOR of
18326 // constants. This specific pattern gets generated when we split a
18327 // selector for a 512 bit vector in a machine without AVX512 (but with
18328 // 256-bit vectors), during legalization:
18329 //
18330 // (vselect (sign_extend (any_extend (BUILD_VECTOR)) i1) LHS RHS)
18331 //
18332 // Iff we find this pattern and the build_vectors are built from
18333 // constants, we translate the vselect into a shuffle_vector that we
18334 // know will be matched by LowerVECTOR_SHUFFLEtoBlend.
18335 if (N->getOpcode() == ISD::VSELECT && !DCI.isBeforeLegalize()) {
18336 SDValue Shuffle = TransformVSELECTtoBlendVECTOR_SHUFFLE(N, DAG, Subtarget);
18337 if (Shuffle.getNode())
18338 return Shuffle;
1827718339 }
1827818340
1827918341 return SDValue();
6868 }
6969
7070 ;CHECK-LABEL: vsel_double8:
71 ;CHECK: vblendvpd
71 ;CHECK: vblendpd $1
72 ;CHECK: vblendpd $1
7273 ;CHECK: ret
7374 define <8 x double> @vsel_double8(<8 x double> %v1, <8 x double> %v2) {
7475 %vsel = select <8 x i1> , <8 x double> %v1, <8 x double> %v2
7677 }
7778
7879 ;CHECK-LABEL: vsel_i648:
79 ;CHECK: vblendvpd
80 ;CHECK: vblendpd $1
81 ;CHECK: vblendpd $1
8082 ;CHECK: ret
8183 define <8 x i64> @vsel_i648(<8 x i64> %v1, <8 x i64> %v2) {
8284 %vsel = select <8 x i1> , <8 x i64> %v1, <8 x i64> %v2
8587
8688 ;CHECK-LABEL: vsel_double4:
8789 ;CHECK-NOT: vinsertf128
88 ;CHECK: vblendpd $5
90 ;CHECK: vshufpd $10
8991 ;CHECK-NEXT: ret
9092 define <4 x double> @vsel_double4(<4 x double> %v1, <4 x double> %v2) {
9193 %vsel = select <4 x i1> , <4 x double> %v1, <4 x double> %v2
110112 %min = select <2 x i1> %min_is_x, <2 x double> %x, <2 x double> %y
111113 ret <2 x double> %min
112114 }
113
114