diff options
| author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-03-11 16:28:11 +0000 |
|---|---|---|
| committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-03-11 16:28:11 +0000 |
| commit | 9a5d0c7540bf1ef3622ebfebaf1404ddc3ddc0ae (patch) | |
| tree | da86dc22d88ae8b957ae00a79dc4019f2e6bda19 /llvm/lib | |
| parent | d2fbd87ce80a1e3fe5cf2a7996efffa4fb3a2e34 (diff) | |
| download | bcm5719-llvm-9a5d0c7540bf1ef3622ebfebaf1404ddc3ddc0ae.tar.gz bcm5719-llvm-9a5d0c7540bf1ef3622ebfebaf1404ddc3ddc0ae.zip | |
[X86][AVX] createVariablePermute - use PSHUFB+PCMPGT+SELECT for v32i8 variable permutes
Same as the VPERMILPS/VPERMILPD approach for v8f32/v4f64 cases, rely on PSHUFB using bits[3:0] for indexing - we can ignore the sign bit (zero element) as those index vector values are considered undefined. The select between the lo/hi permute results based on the index size.
llvm-svn: 327242
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index e046c10252b..2b5e1262458 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -8027,6 +8027,26 @@ SDValue createVariablePermute(MVT VT, SDValue SrcVec, SDValue IndicesVec, ISD::CONCAT_VECTORS, DL, VT, DAG.getNode(X86ISD::VPPERM, DL, MVT::v16i8, LoSrc, HiSrc, LoIdx), DAG.getNode(X86ISD::VPPERM, DL, MVT::v16i8, LoSrc, HiSrc, HiIdx)); + } else if (Subtarget.hasAVX()) { + SDValue Lo = extract128BitVector(SrcVec, 0, DAG, DL); + SDValue Hi = extract128BitVector(SrcVec, 16, DAG, DL); + SDValue LoLo = DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Lo); + SDValue HiHi = DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Hi, Hi); + auto PSHUFBBuilder = [](SelectionDAG &DAG, const SDLoc &DL, + ArrayRef<SDValue> Ops) { + // Permute Lo and Hi and then select based on index range. + // This works as SHUFB uses bits[3:0] to permute elements and we don't + // care about the bit[7] as its just an index vector. + SDValue Idx = Ops[2]; + EVT VT = Idx.getValueType(); + return DAG.getSelectCC(DL, Idx, DAG.getConstant(15, DL, VT), + DAG.getNode(X86ISD::PSHUFB, DL, VT, Ops[1], Idx), + DAG.getNode(X86ISD::PSHUFB, DL, VT, Ops[0], Idx), + ISD::CondCode::SETGT); + }; + SDValue Ops[] = {LoLo, HiHi, IndicesVec}; + return SplitOpsAndApply(DAG, Subtarget, DL, MVT::v32i8, Ops, + PSHUFBBuilder); } break; case MVT::v16i16: |

