aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorJuneyoung Lee <aqjune@gmail.com>2020-03-15 12:09:58 +0900
committerJuneyoung Lee <aqjune@gmail.com>2020-04-25 23:29:54 +0900
commitf5677fe7000e62e4b44782fa72fa5dbcd6a82126 (patch)
treefa96e89e50a4ccc0c424a68a6842c3d3b2ca9634 /llvm/lib/Analysis/ValueTracking.cpp
parent82ce3347273bbc1f67f7e7307007825500588b20 (diff)
downloadllvm-f5677fe7000e62e4b44782fa72fa5dbcd6a82126.zip
llvm-f5677fe7000e62e4b44782fa72fa5dbcd6a82126.tar.gz
llvm-f5677fe7000e62e4b44782fa72fa5dbcd6a82126.tar.bz2
[ValueTracking] Let isGuaranteedNotToBeUndefOrPoison look into more constants/instructions
Summary: This patch helps isGuaranteedNotToBeUndefOrPoison look into more constants and instructions (bitcast/alloca/gep/fcmp). To deal with bitcast, Depth is added to isGuaranteedNotToBeUndefOrPoison. This patch is splitted from https://reviews.llvm.org/D75808. Checked with Alive2 Reviewers: reames, jdoerfert Reviewed By: jdoerfert Subscribers: sanwou01, spatel, llvm-commits, hiraditya Tags: #llvm Differential Revision: https://reviews.llvm.org/D76010
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp64
1 files changed, 47 insertions, 17 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 9caa30b..1c278d8 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4693,7 +4693,11 @@ bool llvm::canCreatePoison(const Instruction *I) {
bool llvm::isGuaranteedNotToBeUndefOrPoison(const Value *V,
const Instruction *CtxI,
- const DominatorTree *DT) {
+ const DominatorTree *DT,
+ unsigned Depth) {
+ if (Depth >= MaxDepth)
+ return false;
+
// If the value is a freeze instruction, then it can never
// be undef or poison.
if (isa<FreezeInst>(V))
@@ -4707,9 +4711,8 @@ bool llvm::isGuaranteedNotToBeUndefOrPoison(const Value *V,
if (isa<UndefValue>(C) || isa<ConstantExpr>(C))
return false;
- // TODO: Add ConstantFP.
- if (isa<ConstantInt>(C) || isa<GlobalVariable>(C) ||
- isa<ConstantPointerNull>(C))
+ if (isa<ConstantInt>(C) || isa<GlobalVariable>(C) || isa<ConstantFP>(V) ||
+ isa<ConstantPointerNull>(C) || isa<Function>(C))
return true;
if (C->getType()->isVectorTy())
@@ -4719,21 +4722,48 @@ bool llvm::isGuaranteedNotToBeUndefOrPoison(const Value *V,
return false;
}
- if (auto PN = dyn_cast<PHINode>(V)) {
- if (llvm::all_of(PN->incoming_values(), [](const Use &U) {
- return isa<ConstantInt>(U.get());
- }))
- return true;
- }
+ // Strip cast operations from a pointer value.
+ // Note that stripPointerCastsSameRepresentation can strip off getelementptr
+ // inbounds with zero offset. To guarantee that the result isn't poison, the
+ // stripped pointer is checked as it has to be pointing into an allocated
+ // object or be null `null` to ensure `inbounds` getelement pointers with a
+ // zero offset could not produce poison.
+ // It can strip off addrspacecast that do not change bit representation as
+ // well. We believe that such addrspacecast is equivalent to no-op.
+ auto *StrippedV = V->stripPointerCastsSameRepresentation();
+ if (isa<AllocaInst>(StrippedV) || isa<GlobalVariable>(StrippedV) ||
+ isa<Function>(StrippedV) || isa<ConstantPointerNull>(StrippedV))
+ return true;
- if (auto II = dyn_cast<ICmpInst>(V)) {
- if (llvm::all_of(II->operands(), [](const Value *V) {
- return isGuaranteedNotToBeUndefOrPoison(V);
- }))
- return true;
- }
+ auto OpCheck = [&](const Value *V) {
+ return isGuaranteedNotToBeUndefOrPoison(V, CtxI, DT, Depth + 1);
+ };
+
+ if (auto *I = dyn_cast<Instruction>(V)) {
+ switch (I->getOpcode()) {
+ case Instruction::GetElementPtr: {
+ auto *GEPI = dyn_cast<GetElementPtrInst>(I);
+ if (!GEPI->isInBounds() && llvm::all_of(GEPI->operands(), OpCheck))
+ return true;
+ break;
+ }
+ case Instruction::FCmp: {
+ auto *FI = dyn_cast<FCmpInst>(I);
+ if (FI->getFastMathFlags().none() &&
+ llvm::all_of(FI->operands(), OpCheck))
+ return true;
+ break;
+ }
+ case Instruction::BitCast:
+ case Instruction::PHI:
+ case Instruction::ICmp:
+ if (llvm::all_of(I->operands(), OpCheck))
+ return true;
+ break;
+ default:
+ break;
+ }
- if (auto I = dyn_cast<Instruction>(V)) {
if (programUndefinedIfPoison(I) && I->getType()->isIntegerTy(1))
// Note: once we have an agreement that poison is a value-wise concept,
// we can remove the isIntegerTy(1) constraint.