diff options
author | Juneyoung Lee <aqjune@gmail.com> | 2021-01-05 10:09:49 +0900 |
---|---|---|
committer | Juneyoung Lee <aqjune@gmail.com> | 2021-01-06 12:10:33 +0900 |
commit | 29f8628d1fc8d96670e13562c4d92fc916bd0ce1 (patch) | |
tree | 1da50486f952374694247a04233515a2ff98c1e8 /llvm/lib | |
parent | 8444a2494d3d58baae373e66f8a7070e03c62cc2 (diff) | |
download | llvm-29f8628d1fc8d96670e13562c4d92fc916bd0ce1.zip llvm-29f8628d1fc8d96670e13562c4d92fc916bd0ce1.tar.gz llvm-29f8628d1fc8d96670e13562c4d92fc916bd0ce1.tar.bz2 |
[Constant] Add containsPoisonElement
This patch
- Adds containsPoisonElement that checks existence of poison in constant vector elements,
- Renames containsUndefElement to containsUndefOrPoisonElement to clarify its behavior & updates its uses properly
With this patch, isGuaranteedNotToBeUndefOrPoison's tests w.r.t constant vectors are added because its analysis is improved.
Thanks!
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D94053
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/IR/ConstantFold.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/IR/Constants.cpp | 25 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp | 4 |
5 files changed, 28 insertions, 15 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index e15d4f0..1c75c5f 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4895,7 +4895,8 @@ static bool isGuaranteedNotToBeUndefOrPoison(const Value *V, return true; if (C->getType()->isVectorTy() && !isa<ConstantExpr>(C)) - return (PoisonOnly || !C->containsUndefElement()) && + return (PoisonOnly ? !C->containsPoisonElement() + : !C->containsUndefOrPoisonElement()) && !C->containsConstantExpression(); } @@ -5636,10 +5637,10 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred, // elements because those can not be back-propagated for analysis. Value *OutputZeroVal = nullptr; if (match(TrueVal, m_AnyZeroFP()) && !match(FalseVal, m_AnyZeroFP()) && - !cast<Constant>(TrueVal)->containsUndefElement()) + !cast<Constant>(TrueVal)->containsUndefOrPoisonElement()) OutputZeroVal = TrueVal; else if (match(FalseVal, m_AnyZeroFP()) && !match(TrueVal, m_AnyZeroFP()) && - !cast<Constant>(FalseVal)->containsUndefElement()) + !cast<Constant>(FalseVal)->containsUndefOrPoisonElement()) OutputZeroVal = FalseVal; if (OutputZeroVal) { diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 4774568..03cb108 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -811,7 +811,7 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond, return true; if (C->getType()->isVectorTy()) - return !C->containsUndefElement() && !C->containsConstantExpression(); + return !C->containsPoisonElement() && !C->containsConstantExpression(); // TODO: Recursively analyze aggregates or other constants. return false; diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index a38302d..5aa819d 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -304,31 +304,42 @@ bool Constant::isElementWiseEqual(Value *Y) const { return isa<UndefValue>(CmpEq) || match(CmpEq, m_One()); } -bool Constant::containsUndefElement() const { - if (auto *VTy = dyn_cast<VectorType>(getType())) { - if (isa<UndefValue>(this)) +static bool +containsUndefinedElement(const Constant *C, + function_ref<bool(const Constant *)> HasFn) { + if (auto *VTy = dyn_cast<VectorType>(C->getType())) { + if (HasFn(C)) return true; - if (isa<ConstantAggregateZero>(this)) + if (isa<ConstantAggregateZero>(C)) return false; - if (isa<ScalableVectorType>(getType())) + if (isa<ScalableVectorType>(C->getType())) return false; for (unsigned i = 0, e = cast<FixedVectorType>(VTy)->getNumElements(); i != e; ++i) - if (isa<UndefValue>(getAggregateElement(i))) + if (HasFn(C->getAggregateElement(i))) return true; } return false; } +bool Constant::containsUndefOrPoisonElement() const { + return containsUndefinedElement( + this, [&](const auto *C) { return isa<UndefValue>(C); }); +} + +bool Constant::containsPoisonElement() const { + return containsUndefinedElement( + this, [&](const auto *C) { return isa<PoisonValue>(C); }); +} + bool Constant::containsConstantExpression() const { if (auto *VTy = dyn_cast<FixedVectorType>(getType())) { for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) if (isa<ConstantExpr>(getAggregateElement(i))) return true; } - return false; } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 87d4b40..0887779 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3370,7 +3370,7 @@ static Value *foldICmpWithLowBitMaskedVal(ICmpInst &I, Type *OpTy = M->getType(); auto *VecC = dyn_cast<Constant>(M); auto *OpVTy = dyn_cast<FixedVectorType>(OpTy); - if (OpVTy && VecC && VecC->containsUndefElement()) { + if (OpVTy && VecC && VecC->containsUndefOrPoisonElement()) { Constant *SafeReplacementConstant = nullptr; for (unsigned i = 0, e = OpVTy->getNumElements(); i != e; ++i) { if (!isa<UndefValue>(VecC->getAggregateElement(i))) { @@ -5259,7 +5259,8 @@ InstCombiner::getFlippedStrictnessPredicateAndConstant(CmpInst::Predicate Pred, // It may not be safe to change a compare predicate in the presence of // undefined elements, so replace those elements with the first safe constant // that we found. - if (C->containsUndefElement()) { + // TODO: in case of poison, it is safe; let's replace undefs only. + if (C->containsUndefOrPoisonElement()) { assert(SafeReplacementConstant && "Replacement constant not set"); C = Constant::replaceUndefsWith(C, SafeReplacementConstant); } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp index 494c58e..7718c8b 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp @@ -239,8 +239,8 @@ LLVM_NODISCARD Value *Negator::visitImpl(Value *V, unsigned Depth) { // While this is normally not behind a use-check, // let's consider division to be special since it's costly. if (auto *Op1C = dyn_cast<Constant>(I->getOperand(1))) { - if (!Op1C->containsUndefElement() && Op1C->isNotMinSignedValue() && - Op1C->isNotOneValue()) { + if (!Op1C->containsUndefOrPoisonElement() && + Op1C->isNotMinSignedValue() && Op1C->isNotOneValue()) { Value *BO = Builder.CreateSDiv(I->getOperand(0), ConstantExpr::getNeg(Op1C), I->getName() + ".neg"); |