aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-07-14 00:29:50 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-07-14 00:29:50 +0000
commit7f781aba9755633c53210db02d51f6f56d11ea48 (patch)
tree939807d2484ee567af45c3c88bf2e4724b205d14 /llvm/lib/Analysis/ConstantFolding.cpp
parent63497c649245cc384c2986f63f713bef490d8da2 (diff)
downloadllvm-7f781aba9755633c53210db02d51f6f56d11ea48.zip
llvm-7f781aba9755633c53210db02d51f6f56d11ea48.tar.gz
llvm-7f781aba9755633c53210db02d51f6f56d11ea48.tar.bz2
[ConstantFolding] Fold masked loads
We can constant fold a masked load if the operands are appropriately constant. Differential Revision: http://reviews.llvm.org/D22324 llvm-svn: 275352
Diffstat (limited to 'llvm/lib/Analysis/ConstantFolding.cpp')
-rw-r--r--llvm/lib/Analysis/ConstantFolding.cpp37
1 files changed, 36 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index dcfe700..96a2d02ed 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1299,6 +1299,7 @@ bool llvm::canConstantFoldCallTo(const Function *F) {
case Intrinsic::fmuladd:
case Intrinsic::copysign:
case Intrinsic::round:
+ case Intrinsic::masked_load:
case Intrinsic::sadd_with_overflow:
case Intrinsic::uadd_with_overflow:
case Intrinsic::ssub_with_overflow:
@@ -1843,11 +1844,44 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,
Constant *ConstantFoldVectorCall(StringRef Name, unsigned IntrinsicID,
VectorType *VTy, ArrayRef<Constant *> Operands,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI) {
SmallVector<Constant *, 4> Result(VTy->getNumElements());
SmallVector<Constant *, 4> Lane(Operands.size());
Type *Ty = VTy->getElementType();
+ if (IntrinsicID == Intrinsic::masked_load) {
+ auto *SrcPtr = Operands[0];
+ auto *Mask = Operands[2];
+ auto *Passthru = Operands[3];
+ Constant *VecData = ConstantFoldLoadFromConstPtr(SrcPtr, VTy, DL);
+ if (!VecData)
+ return nullptr;
+
+ SmallVector<Constant *, 32> NewElements;
+ for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) {
+ auto *MaskElt =
+ dyn_cast_or_null<ConstantInt>(Mask->getAggregateElement(I));
+ if (!MaskElt)
+ break;
+ if (MaskElt->isZero()) {
+ auto *PassthruElt = Passthru->getAggregateElement(I);
+ if (!PassthruElt)
+ break;
+ NewElements.push_back(PassthruElt);
+ } else {
+ assert(MaskElt->isOne());
+ auto *VecElt = VecData->getAggregateElement(I);
+ if (!VecElt)
+ break;
+ NewElements.push_back(VecElt);
+ }
+ }
+ if (NewElements.size() == VTy->getNumElements())
+ return ConstantVector::get(NewElements);
+ return nullptr;
+ }
+
for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) {
// Gather a column of constants.
for (unsigned J = 0, JE = Operands.size(); J != JE; ++J) {
@@ -1880,7 +1914,8 @@ llvm::ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands,
Type *Ty = F->getReturnType();
if (auto *VTy = dyn_cast<VectorType>(Ty))
- return ConstantFoldVectorCall(Name, F->getIntrinsicID(), VTy, Operands, TLI);
+ return ConstantFoldVectorCall(Name, F->getIntrinsicID(), VTy, Operands,
+ F->getParent()->getDataLayout(), TLI);
return ConstantFoldScalarCall(Name, F->getIntrinsicID(), Ty, Operands, TLI);
}