diff options
| author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2016-05-01 16:41:22 +0000 |
|---|---|---|
| committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2016-05-01 16:41:22 +0000 |
| commit | 8cddf8b3c6ca78b2ff2ae1c01ebc27304e6d9834 (patch) | |
| tree | 3eacd02ed55654b81cfe16dab9c6b1f5dd3d3d00 /llvm/lib/Transforms | |
| parent | 33ae13d3c3bf919b7c12167ddb3d13b4c2fcd9c5 (diff) | |
| download | bcm5719-llvm-8cddf8b3c6ca78b2ff2ae1c01ebc27304e6d9834.tar.gz bcm5719-llvm-8cddf8b3c6ca78b2ff2ae1c01ebc27304e6d9834.zip | |
[InstCombine][AVX2] Combine VPERMD/VPERMPS intrinsics with constant masks to shufflevector.
llvm-svn: 268199
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 10be4b9877c..307bb9f9806 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -681,6 +681,37 @@ static Value *simplifyX86vpermilvar(const IntrinsicInst &II, return Builder.CreateShuffleVector(V1, V2, ShuffleMask); } +/// Attempt to convert vpermd/vpermps to shufflevector if the mask is constant. +static Value *simplifyX86vpermv(const IntrinsicInst &II, + InstCombiner::BuilderTy &Builder) { + auto *V = dyn_cast<Constant>(II.getArgOperand(1)); + if (!V) + return nullptr; + + VectorType *VecTy = cast<VectorType>(II.getType()); + unsigned Size = VecTy->getNumElements(); + assert(Size == 8 && "Unexpected shuffle mask size"); + + // Initialize the resulting shuffle mask to all zeroes. + uint32_t Indexes[8] = {0}; + + for (unsigned I = 0; I < Size; ++I) { + Constant *COp = V->getAggregateElement(I); + if (!COp || !isa<ConstantInt>(COp)) + return nullptr; + + APInt Index = cast<ConstantInt>(COp)->getValue(); + Index = Index.getLoBits(3); + Indexes[I] = (uint32_t)Index.getZExtValue(); + } + + auto ShuffleMask = + ConstantDataVector::get(II.getContext(), makeArrayRef(Indexes, Size)); + auto V1 = II.getArgOperand(0); + auto V2 = UndefValue::get(VecTy); + return Builder.CreateShuffleVector(V1, V2, ShuffleMask); +} + /// The shuffle mask for a perm2*128 selects any two halves of two 256-bit /// source vectors, unless a zero bit is set. If a zero bit is set, /// then ignore that half of the mask and clear that half of the vector. @@ -1751,6 +1782,12 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { return replaceInstUsesWith(*II, V); break; + case Intrinsic::x86_avx2_permd: + case Intrinsic::x86_avx2_permps: + if (Value *V = simplifyX86vpermv(*II, *Builder)) + return replaceInstUsesWith(*II, V); + break; + case Intrinsic::x86_avx_vperm2f128_pd_256: case Intrinsic::x86_avx_vperm2f128_ps_256: case Intrinsic::x86_avx_vperm2f128_si_256: |

