summaryrefslogtreecommitdiff
path: root/lib/VMCore/Instructions.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2012-01-25 23:49:49 +0000
committerChris Lattner <sabre@nondot.org>2012-01-25 23:49:49 +0000
commit83694a984c153a0d78dcfb47d464c9a1561c22ef (patch)
tree919a8e15ddab3284665cf315871e6e8771ab85d3 /lib/VMCore/Instructions.cpp
parente8838d5c5f6cae7daa2507a114c896dc5a4ae097 (diff)
downloadllvm-83694a984c153a0d78dcfb47d464c9a1561c22ef.tar.gz
llvm-83694a984c153a0d78dcfb47d464c9a1561c22ef.tar.bz2
llvm-83694a984c153a0d78dcfb47d464c9a1561c22ef.tar.xz
add some helper methods to ShuffleVectorInst and enhance its
"isValidOperands" and "getMaskValue" methods to allow ConstantDataSequential. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148998 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/Instructions.cpp')
-rw-r--r--lib/VMCore/Instructions.cpp83
1 files changed, 55 insertions, 28 deletions
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index d221af0786..46d5e7a448 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -1576,53 +1576,84 @@ ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
const Value *Mask) {
+ // V1 and V2 must be vectors of the same type.
if (!V1->getType()->isVectorTy() || V1->getType() != V2->getType())
return false;
+ // Mask must be vector of i32.
VectorType *MaskTy = dyn_cast<VectorType>(Mask->getType());
if (MaskTy == 0 || !MaskTy->getElementType()->isIntegerTy(32))
return false;
// Check to see if Mask is valid.
+ if (isa<UndefValue>(Mask) || isa<ConstantAggregateZero>(Mask))
+ return true;
+
if (const ConstantVector *MV = dyn_cast<ConstantVector>(Mask)) {
- VectorType *VTy = cast<VectorType>(V1->getType());
+ unsigned V1Size = cast<VectorType>(V1->getType())->getNumElements();
for (unsigned i = 0, e = MV->getNumOperands(); i != e; ++i) {
- if (ConstantInt* CI = dyn_cast<ConstantInt>(MV->getOperand(i))) {
- if (CI->uge(VTy->getNumElements()*2))
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(MV->getOperand(i))) {
+ if (CI->uge(V1Size*2))
return false;
} else if (!isa<UndefValue>(MV->getOperand(i))) {
return false;
}
}
- } else if (!isa<UndefValue>(Mask) && !isa<ConstantAggregateZero>(Mask)) {
- // The bitcode reader can create a place holder for a forward reference
- // used as the shuffle mask. When this occurs, the shuffle mask will
- // fall into this case and fail. To avoid this error, do this bit of
- // ugliness to allow such a mask pass.
- if (const ConstantExpr* CE = dyn_cast<ConstantExpr>(Mask)) {
- if (CE->getOpcode() == Instruction::UserOp1)
- return true;
- }
- return false;
+ return true;
}
- return true;
+
+ if (const ConstantDataSequential *CDS =
+ dyn_cast<ConstantDataSequential>(Mask)) {
+ unsigned V1Size = cast<VectorType>(V1->getType())->getNumElements();
+ for (unsigned i = 0, e = MaskTy->getNumElements(); i != e; ++i)
+ if (CDS->getElementAsInteger(i) >= V1Size*2)
+ return false;
+ return true;
+ }
+
+ // The bitcode reader can create a place holder for a forward reference
+ // used as the shuffle mask. When this occurs, the shuffle mask will
+ // fall into this case and fail. To avoid this error, do this bit of
+ // ugliness to allow such a mask pass.
+ if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(Mask))
+ if (CE->getOpcode() == Instruction::UserOp1)
+ return true;
+
+ return false;
}
/// getMaskValue - Return the index from the shuffle mask for the specified
/// output result. This is either -1 if the element is undef or a number less
/// than 2*numelements.
int ShuffleVectorInst::getMaskValue(unsigned i) const {
- const Constant *Mask = cast<Constant>(getOperand(2));
- if (isa<UndefValue>(Mask)) return -1;
- if (isa<ConstantAggregateZero>(Mask)) return 0;
- const ConstantVector *MaskCV = cast<ConstantVector>(Mask);
- assert(i < MaskCV->getNumOperands() && "Index out of range");
-
- if (isa<UndefValue>(MaskCV->getOperand(i)))
+ assert(i < getType()->getNumElements() && "Index out of range");
+ if (ConstantDataSequential *CDS =dyn_cast<ConstantDataSequential>(getMask()))
+ return CDS->getElementAsInteger(i);
+ Constant *C = getMask()->getAggregateElement(i);
+ if (isa<UndefValue>(C))
return -1;
- return cast<ConstantInt>(MaskCV->getOperand(i))->getZExtValue();
+ return cast<ConstantInt>(C)->getZExtValue();
}
+/// getShuffleMask - Return the full mask for this instruction, where each
+/// element is the element number and undef's are returned as -1.
+void ShuffleVectorInst::getShuffleMask(SmallVectorImpl<int> &Result) const {
+ unsigned NumElts = getType()->getNumElements();
+
+ if (ConstantDataSequential *CDS=dyn_cast<ConstantDataSequential>(getMask())) {
+ for (unsigned i = 0; i != NumElts; ++i)
+ Result.push_back(CDS->getElementAsInteger(i));
+ return;
+ }
+ Constant *Mask = getMask();
+ for (unsigned i = 0; i != NumElts; ++i) {
+ Constant *C = Mask->getAggregateElement(i);
+ Result.push_back(isa<UndefValue>(C) ? -1 :
+ cast<ConstantInt>(Mask)->getZExtValue());
+ }
+}
+
+
//===----------------------------------------------------------------------===//
// InsertValueInst Class
//===----------------------------------------------------------------------===//
@@ -3457,15 +3488,11 @@ ExtractElementInst *ExtractElementInst::clone_impl() const {
}
InsertElementInst *InsertElementInst::clone_impl() const {
- return InsertElementInst::Create(getOperand(0),
- getOperand(1),
- getOperand(2));
+ return InsertElementInst::Create(getOperand(0), getOperand(1), getOperand(2));
}
ShuffleVectorInst *ShuffleVectorInst::clone_impl() const {
- return new ShuffleVectorInst(getOperand(0),
- getOperand(1),
- getOperand(2));
+ return new ShuffleVectorInst(getOperand(0), getOperand(1), getOperand(2));
}
PHINode *PHINode::clone_impl() const {