diff options
author | Juneyoung Lee <aqjune@gmail.com> | 2020-03-15 12:09:58 +0900 |
---|---|---|
committer | Juneyoung Lee <aqjune@gmail.com> | 2020-04-25 23:29:54 +0900 |
commit | f5677fe7000e62e4b44782fa72fa5dbcd6a82126 (patch) | |
tree | fa96e89e50a4ccc0c424a68a6842c3d3b2ca9634 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 82ce3347273bbc1f67f7e7307007825500588b20 (diff) | |
download | llvm-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.cpp | 64 |
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. |