summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2016-05-01 16:41:22 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2016-05-01 16:41:22 +0000
commit8cddf8b3c6ca78b2ff2ae1c01ebc27304e6d9834 (patch)
tree3eacd02ed55654b81cfe16dab9c6b1f5dd3d3d00 /llvm/lib/Transforms
parent33ae13d3c3bf919b7c12167ddb3d13b4c2fcd9c5 (diff)
downloadbcm5719-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.cpp37
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:
OpenPOWER on IntegriCloud