summaryrefslogtreecommitdiff
path: root/lib/IR/AutoUpgrade.cpp
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2017-01-03 05:45:46 +0000
committerCraig Topper <craig.topper@gmail.com>2017-01-03 05:45:46 +0000
commitbe3e531ac2cf2a25563d763a9418caf6709b706e (patch)
treee43d7b472d310480627b7c899bd4f0fc410e0f85 /lib/IR/AutoUpgrade.cpp
parentf61ad6ec119554f251f44f54c9cf42d8b713866e (diff)
[AVX-512] Remove vextract intrinsics and autoupgrade to native shufflevectors. This unfortunately generates some really terrible code without VLX support due to v2i1 and v4i1 not being legal.
Hopefully we can improve that in future patches. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290863 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR/AutoUpgrade.cpp')
-rw-r--r--lib/IR/AutoUpgrade.cpp26
1 files changed, 16 insertions, 10 deletions
diff --git a/lib/IR/AutoUpgrade.cpp b/lib/IR/AutoUpgrade.cpp
index 2d9d0f95efa..c6c6f0055d6 100644
--- a/lib/IR/AutoUpgrade.cpp
+++ b/lib/IR/AutoUpgrade.cpp
@@ -344,6 +344,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
Name == "avx2.vinserti128" || // Added in 3.7
Name.startswith("avx.vextractf128.") || // Added in 3.7
Name == "avx2.vextracti128" || // Added in 3.7
+ Name.startswith("avx512.mask.vextract") || // Added in 4.0
Name.startswith("sse4a.movnt.") || // Added in 3.9
Name.startswith("avx.movnt.") || // Added in 3.2
Name.startswith("avx512.storent.") || // Added in 3.9
@@ -1188,23 +1189,28 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
Idxs[i] = Imm ? (i + NumElts / 2) : i;
Rep = Builder.CreateShuffleVector(Op0, Rep, Idxs);
} else if (IsX86 && (Name.startswith("avx.vextractf128.") ||
- Name == "avx2.vextracti128")) {
+ Name == "avx2.vextracti128" ||
+ Name.startswith("avx512.mask.vextract"))) {
Value *Op0 = CI->getArgOperand(0);
unsigned Imm = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
- VectorType *VecTy = cast<VectorType>(CI->getType());
- unsigned NumElts = VecTy->getNumElements();
+ unsigned DstNumElts = CI->getType()->getVectorNumElements();
+ unsigned SrcNumElts = Op0->getType()->getVectorNumElements();
+ unsigned Scale = SrcNumElts / DstNumElts;
// Mask off the high bits of the immediate value; hardware ignores those.
- Imm = Imm & 1;
+ Imm = Imm % Scale;
- // Get indexes for either the high half or low half of the input vector.
- SmallVector<uint32_t, 4> Idxs(NumElts);
- for (unsigned i = 0; i != NumElts; ++i) {
- Idxs[i] = Imm ? (i + NumElts) : i;
+ // Get indexes for the subvector of the input vector.
+ SmallVector<uint32_t, 8> Idxs(DstNumElts);
+ for (unsigned i = 0; i != DstNumElts; ++i) {
+ Idxs[i] = i + (Imm * DstNumElts);
}
+ Rep = Builder.CreateShuffleVector(Op0, Op0, Idxs);
- Value *UndefV = UndefValue::get(Op0->getType());
- Rep = Builder.CreateShuffleVector(Op0, UndefV, Idxs);
+ // If the intrinsic has a mask operand, handle that.
+ if (CI->getNumArgOperands() == 4)
+ Rep = EmitX86Select(Builder, CI->getArgOperand(3), Rep,
+ CI->getArgOperand(2));
} else if (!IsX86 && Name == "stackprotectorcheck") {
Rep = nullptr;
} else if (IsX86 && (Name.startswith("avx512.mask.perm.df.") ||