aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Constants.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2019-12-10 15:41:19 -0500
committerSanjay Patel <spatel@rotateright.com>2019-12-10 17:16:59 -0500
commit16e9315685bc057849eab072de6ec349b508ec1d (patch)
treec5f15042090124e48985a1f37f0aab08e5e57d23 /llvm/lib/IR/Constants.cpp
parent252d3b9805f8064837630deb282f653ac2978096 (diff)
downloadllvm-16e9315685bc057849eab072de6ec349b508ec1d.zip
llvm-16e9315685bc057849eab072de6ec349b508ec1d.tar.gz
llvm-16e9315685bc057849eab072de6ec349b508ec1d.tar.bz2
[IR] allow undefined elements when checking for splat constants
This mimics the related call in SDAG. The caller is responsible for ensuring that undef values are propagated safely.
Diffstat (limited to 'llvm/lib/IR/Constants.cpp')
-rw-r--r--llvm/lib/IR/Constants.cpp27
1 files changed, 22 insertions, 5 deletions
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index fc215d6..cafb412 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -1442,24 +1442,41 @@ void ConstantVector::destroyConstantImpl() {
getType()->getContext().pImpl->VectorConstants.remove(this);
}
-Constant *Constant::getSplatValue() const {
+Constant *Constant::getSplatValue(bool AllowUndefs) const {
assert(this->getType()->isVectorTy() && "Only valid for vectors!");
if (isa<ConstantAggregateZero>(this))
return getNullValue(this->getType()->getVectorElementType());
if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
return CV->getSplatValue();
if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
- return CV->getSplatValue();
+ return CV->getSplatValue(AllowUndefs);
return nullptr;
}
-Constant *ConstantVector::getSplatValue() const {
+Constant *ConstantVector::getSplatValue(bool AllowUndefs) const {
// Check out first element.
Constant *Elt = getOperand(0);
// Then make sure all remaining elements point to the same value.
- for (unsigned I = 1, E = getNumOperands(); I < E; ++I)
- if (getOperand(I) != Elt)
+ for (unsigned I = 1, E = getNumOperands(); I < E; ++I) {
+ Constant *OpC = getOperand(I);
+ if (OpC == Elt)
+ continue;
+
+ // Strict mode: any mismatch is not a splat.
+ if (!AllowUndefs)
return nullptr;
+
+ // Allow undefs mode: ignore undefined elements.
+ if (isa<UndefValue>(OpC))
+ continue;
+
+ // If we do not have a defined element yet, use the current operand.
+ if (isa<UndefValue>(Elt))
+ Elt = OpC;
+
+ if (OpC != Elt)
+ return nullptr;
+ }
return Elt;
}