summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2018-03-11 16:28:11 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2018-03-11 16:28:11 +0000
commit9a5d0c7540bf1ef3622ebfebaf1404ddc3ddc0ae (patch)
treeda86dc22d88ae8b957ae00a79dc4019f2e6bda19 /llvm/lib
parentd2fbd87ce80a1e3fe5cf2a7996efffa4fb3a2e34 (diff)
downloadbcm5719-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.cpp20
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:
OpenPOWER on IntegriCloud