summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/VectorUtils.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-07-13 01:15:53 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-07-13 01:15:53 +0000
commit599ca4426cb5c0cf90c8d0e409142e2649dc7dd6 (patch)
tree84b4e2e6c163b4fd8041a619b67d23acd573466b /llvm/lib/Analysis/VectorUtils.cpp
parent25a796e148887e50c743b9aa93765e8c5f1f1faa (diff)
downloadbcm5719-llvm-599ca4426cb5c0cf90c8d0e409142e2649dc7dd6.tar.gz
bcm5719-llvm-599ca4426cb5c0cf90c8d0e409142e2649dc7dd6.zip
[InstSimplify] Teach InstSimplify how to simplify extractelement
llvm-svn: 242008
Diffstat (limited to 'llvm/lib/Analysis/VectorUtils.cpp')
-rw-r--r--llvm/lib/Analysis/VectorUtils.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/VectorUtils.cpp b/llvm/lib/Analysis/VectorUtils.cpp
index eab5887a17e..67f68dc8391 100644
--- a/llvm/lib/Analysis/VectorUtils.cpp
+++ b/llvm/lib/Analysis/VectorUtils.cpp
@@ -357,3 +357,55 @@ llvm::Value *llvm::getStrideFromPointer(llvm::Value *Ptr, ScalarEvolution *SE,
return Stride;
}
+
+/// \brief Given a vector and an element number, see if the scalar value is
+/// already around as a register, for example if it were inserted then extracted
+/// from the vector.
+llvm::Value *llvm::findScalarElement(llvm::Value *V, unsigned EltNo) {
+ assert(V->getType()->isVectorTy() && "Not looking at a vector?");
+ VectorType *VTy = cast<VectorType>(V->getType());
+ unsigned Width = VTy->getNumElements();
+ if (EltNo >= Width) // Out of range access.
+ return UndefValue::get(VTy->getElementType());
+
+ if (Constant *C = dyn_cast<Constant>(V))
+ return C->getAggregateElement(EltNo);
+
+ if (InsertElementInst *III = dyn_cast<InsertElementInst>(V)) {
+ // If this is an insert to a variable element, we don't know what it is.
+ if (!isa<ConstantInt>(III->getOperand(2)))
+ return nullptr;
+ unsigned IIElt = cast<ConstantInt>(III->getOperand(2))->getZExtValue();
+
+ // If this is an insert to the element we are looking for, return the
+ // inserted value.
+ if (EltNo == IIElt)
+ return III->getOperand(1);
+
+ // Otherwise, the insertelement doesn't modify the value, recurse on its
+ // vector input.
+ return findScalarElement(III->getOperand(0), EltNo);
+ }
+
+ if (ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(V)) {
+ unsigned LHSWidth = SVI->getOperand(0)->getType()->getVectorNumElements();
+ int InEl = SVI->getMaskValue(EltNo);
+ if (InEl < 0)
+ return UndefValue::get(VTy->getElementType());
+ if (InEl < (int)LHSWidth)
+ return findScalarElement(SVI->getOperand(0), InEl);
+ return findScalarElement(SVI->getOperand(1), InEl - LHSWidth);
+ }
+
+ // Extract a value from a vector add operation with a constant zero.
+ Value *Val = nullptr; Constant *Con = nullptr;
+ if (match(V,
+ llvm::PatternMatch::m_Add(llvm::PatternMatch::m_Value(Val),
+ llvm::PatternMatch::m_Constant(Con)))) {
+ if (Con->getAggregateElement(EltNo)->isNullValue())
+ return findScalarElement(Val, EltNo);
+ }
+
+ // Otherwise, we don't know.
+ return nullptr;
+}
OpenPOWER on IntegriCloud