aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/AutoUpgrade.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/AutoUpgrade.cpp')
-rw-r--r--llvm/lib/IR/AutoUpgrade.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index ce0b10d..52dd90f 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -194,6 +194,16 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
Name.startswith("x86.sse.storeu.") ||
Name.startswith("x86.sse2.storeu.") ||
Name.startswith("x86.avx.storeu.") ||
+ Name.startswith("x86.avx512.mask.storeu.p") ||
+ Name.startswith("x86.avx512.mask.storeu.b.") ||
+ Name.startswith("x86.avx512.mask.storeu.w.") ||
+ Name.startswith("x86.avx512.mask.storeu.d.") ||
+ Name.startswith("x86.avx512.mask.storeu.q.") ||
+ Name.startswith("x86.avx512.mask.store.p") ||
+ Name.startswith("x86.avx512.mask.store.b.") ||
+ Name.startswith("x86.avx512.mask.store.w.") ||
+ Name.startswith("x86.avx512.mask.store.d.") ||
+ Name.startswith("x86.avx512.mask.store.q.") ||
Name == "x86.sse42.crc32.64.8" ||
Name.startswith("x86.avx.vbroadcast.s") ||
Name.startswith("x86.sse2.psll.dq") ||
@@ -358,6 +368,40 @@ static Value *UpgradeX86PSRLDQIntrinsics(IRBuilder<> &Builder, LLVMContext &C,
return Builder.CreateBitCast(Res, ResultTy, "cast");
}
+static Value *UpgradeMaskedStore(IRBuilder<> &Builder, LLVMContext &C,
+ Value *Ptr, Value *Data, Value *Mask,
+ bool Aligned) {
+ // Cast the pointer to the right type.
+ Ptr = Builder.CreateBitCast(Ptr,
+ llvm::PointerType::getUnqual(Data->getType()));
+ unsigned Align =
+ Aligned ? cast<VectorType>(Data->getType())->getBitWidth() / 8 : 1;
+
+ // If the mask is all ones just emit a regular store.
+ if (const auto *C = dyn_cast<Constant>(Mask))
+ if (C->isAllOnesValue())
+ return Builder.CreateAlignedStore(Data, Ptr, Align);
+
+ // Convert the mask from an integer type to a vector of i1.
+ unsigned NumElts = Data->getType()->getVectorNumElements();
+ llvm::VectorType *MaskTy = llvm::VectorType::get(Builder.getInt1Ty(),
+ cast<IntegerType>(Mask->getType())->getBitWidth());
+ Mask = Builder.CreateBitCast(Mask, MaskTy);
+
+ // If we have less than 8 elements, then the starting mask was an i8 and
+ // we need to extract down to the right number of elements.
+ if (NumElts < 8) {
+ int Indices[4];
+ for (unsigned i = 0; i != NumElts; ++i)
+ Indices[i] = i;
+ Mask = Builder.CreateShuffleVector(Mask, Mask,
+ makeArrayRef(Indices, NumElts),
+ "extract");
+ }
+
+ return Builder.CreateMaskedStore(Data, Ptr, Align, Mask);
+}
+
// UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the
// upgraded intrinsic. All argument and return casting must be provided in
// order to seamlessly integrate with existing context.
@@ -459,6 +503,28 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
// Remove intrinsic.
CI->eraseFromParent();
return;
+ } else if (Name.startswith("llvm.x86.avx512.mask.storeu.p") ||
+ Name.startswith("llvm.x86.avx512.mask.storeu.b.") ||
+ Name.startswith("llvm.x86.avx512.mask.storeu.w.") ||
+ Name.startswith("llvm.x86.avx512.mask.storeu.d.") ||
+ Name.startswith("llvm.x86.avx512.mask.storeu.q.")) {
+ UpgradeMaskedStore(Builder, C, CI->getArgOperand(0), CI->getArgOperand(1),
+ CI->getArgOperand(2), /*Aligned*/false);
+
+ // Remove intrinsic.
+ CI->eraseFromParent();
+ return;
+ } else if (Name.startswith("llvm.x86.avx512.mask.store.p") ||
+ Name.startswith("llvm.x86.avx512.mask.store.b.") ||
+ Name.startswith("llvm.x86.avx512.mask.store.w.") ||
+ Name.startswith("llvm.x86.avx512.mask.store.d.") ||
+ Name.startswith("llvm.x86.avx512.mask.store.q.")) {
+ UpgradeMaskedStore(Builder, C, CI->getArgOperand(0), CI->getArgOperand(1),
+ CI->getArgOperand(2), /*Aligned*/true);
+
+ // Remove intrinsic.
+ CI->eraseFromParent();
+ return;
} else if (Name.startswith("llvm.x86.xop.vpcom")) {
Intrinsic::ID intID;
if (Name.endswith("ub"))