From d9dc114e2f6ab41192e4a7127924e426ab42feee Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Sat, 10 Mar 2018 18:12:35 +0000 Subject: [PATCH] [X86][SSE] createVariablePermute - create index scaling helper. NFCI. This will help in some future changes for custom lowering. llvm-svn: 327217 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 49 +++++++++++++------------ 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index f10c23504d5a..2b4cd5d9e30d 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -7934,6 +7934,30 @@ SDValue createVariablePermute(MVT VT, SDValue SrcVec, SDValue IndicesVec, DAG.getNode(ISD::INSERT_SUBVECTOR, SDLoc(SrcVec), VT, DAG.getUNDEF(VT), SrcVec, DAG.getIntPtrConstant(0, SDLoc(SrcVec))); + auto ScaleIndices = [&DAG](SDValue Idx, uint64_t Scale) { + assert(isPowerOf2_64(Scale) && "Illegal variable permute shuffle scale"); + EVT SrcVT = Idx.getValueType(); + unsigned NumDstBits = SrcVT.getScalarSizeInBits() / Scale; + uint64_t IndexScale = 0; + uint64_t IndexOffset = 0; + + // If we're scaling a smaller permute op, then we need to repeat the + // indices, scaling and offsetting them as well. + // e.g. v4i32 -> v16i8 (Scale = 4) + // IndexScale = v4i32 Splat(4 << 24 | 4 << 16 | 4 << 8 | 4) + // IndexOffset = v4i32 Splat(3 << 24 | 2 << 16 | 1 << 8 | 0) + for (uint64_t i = 0; i != Scale; ++i) { + IndexScale |= Scale << (i * NumDstBits); + IndexOffset |= i << (i * NumDstBits); + } + + Idx = DAG.getNode(ISD::MUL, SDLoc(Idx), SrcVT, Idx, + DAG.getConstant(IndexScale, SDLoc(Idx), SrcVT)); + Idx = DAG.getNode(ISD::ADD, SDLoc(Idx), SrcVT, Idx, + DAG.getConstant(IndexOffset, SDLoc(Idx), SrcVT)); + return Idx; + }; + unsigned Opcode = 0; switch (VT.SimpleTy) { default: @@ -8025,29 +8049,8 @@ SDValue createVariablePermute(MVT VT, SDValue SrcVec, SDValue IndicesVec, "Illegal variable permute shuffle type"); uint64_t Scale = VT.getScalarSizeInBits() / ShuffleVT.getScalarSizeInBits(); - if (Scale > 1) { - assert(isPowerOf2_64(Scale) && "Illegal variable permute shuffle scale"); - unsigned ShuffleBits = ShuffleVT.getScalarSizeInBits(); - uint64_t IndexScale = 0; - uint64_t IndexOffset = 0; - - // If we're scaling a smaller permute op, then we need to repeat the - // indices, scaling and offsetting them as well. - // e.g. v4i32 -> v16i8 (Scale = 4) - // IndexScale = v4i32 Splat(4 << 24 | 4 << 16 | 4 << 8 | 4) - // IndexOffset = v4i32 Splat(3 << 24 | 2 << 16 | 1 << 8 | 0) - for (uint64_t i = 0; i != Scale; ++i) { - IndexScale |= Scale << (i * ShuffleBits); - IndexOffset |= i << (i * ShuffleBits); - } - - IndicesVec = - DAG.getNode(ISD::MUL, SDLoc(IndicesVec), IndicesVT, IndicesVec, - DAG.getConstant(IndexScale, SDLoc(IndicesVec), IndicesVT)); - IndicesVec = - DAG.getNode(ISD::ADD, SDLoc(IndicesVec), IndicesVT, IndicesVec, - DAG.getConstant(IndexOffset, SDLoc(IndicesVec), IndicesVT)); - } + if (Scale > 1) + IndicesVec = ScaleIndices(IndicesVec, Scale); EVT ShuffleIdxVT = EVT(ShuffleVT).changeVectorElementTypeToInteger(); IndicesVec = DAG.getBitcast(ShuffleIdxVT, IndicesVec);