summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/LazyValueInfo.cpp
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2017-08-01 05:30:49 +0000
committerDaniel Jasper <djasper@google.com>2017-08-01 05:30:49 +0000
commit43cd2ef49c843c0478569dfdb375d7c30ad0012a (patch)
treea7925fcb58c7f192a2e570b29e076146a25e5ec7 /llvm/lib/Analysis/LazyValueInfo.cpp
parent8882ac2ac911e6a4478ca516ce345fa8339ef9d9 (diff)
downloadbcm5719-llvm-43cd2ef49c843c0478569dfdb375d7c30ad0012a.tar.gz
bcm5719-llvm-43cd2ef49c843c0478569dfdb375d7c30ad0012a.zip
Revert r309415: "[LVI] Constant-propagate a zero extension of the switch condition value through case edges"
This causes assertion failures in (a somewhat old version of) SpiderMonkey. I have already forwarded reproduction instructions to the patch author. llvm-svn: 309659
Diffstat (limited to 'llvm/lib/Analysis/LazyValueInfo.cpp')
-rw-r--r--llvm/lib/Analysis/LazyValueInfo.cpp112
1 files changed, 4 insertions, 108 deletions
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 303bb6168f8..102081e721a 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -17,7 +17,6 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/ConstantFolding.h"
-#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
@@ -149,15 +148,6 @@ public:
return Range;
}
- Optional<APInt> asConstantInteger() const {
- if (isConstant() && isa<ConstantInt>(Val)) {
- return Val->getUniqueInteger();
- } else if (isConstantRange() && Range.isSingleElement()) {
- return *Range.getSingleElement();
- }
- return Optional<APInt>();
- }
-
private:
void markOverdefined() {
if (isOverdefined())
@@ -1365,42 +1355,6 @@ LVILatticeVal getValueFromCondition(Value *Val, Value *Cond, bool isTrueDest) {
return getValueFromCondition(Val, Cond, isTrueDest, Visited);
}
-// Return true if Usr has Op as an operand, otherwise false.
-static bool usesOperand(User *Usr, Value *Op) {
- return find(Usr->operands(), Op) != Usr->op_end();
-}
-
-// Check if Val can be simplified to an integer constant when the value of one
-// of its operands Op is an integer constant OpConstVal. If so, return it as an
-// lattice value range with a single element or otherwise return an overdefined
-// lattice value.
-static LVILatticeVal constantFoldUser(Value *Val, Value *Op,
- const APInt &OpConstVal,
- const DataLayout &DL) {
- Constant* OpConst = Constant::getIntegerValue(Op->getType(), OpConstVal);
- // Check if Val can be simplified to a constant.
- if (auto *CI = dyn_cast<CastInst>(Val)) {
- assert(CI->getOperand(0) == Op && "Operand 0 isn't Op");
- if (auto *C = dyn_cast_or_null<ConstantInt>(
- SimplifyCastInst(CI->getOpcode(), OpConst,
- CI->getDestTy(), DL))) {
- return LVILatticeVal::getRange(ConstantRange(C->getUniqueInteger()));
- }
- } else if (auto *BO = dyn_cast<BinaryOperator>(Val)) {
- bool Op0Match = BO->getOperand(0) == Op;
- bool Op1Match = BO->getOperand(1) == Op;
- assert((Op0Match || Op1Match) &&
- "Operand 0 nor Operand 1 isn't a match");
- Value *LHS = Op0Match ? OpConst : BO->getOperand(0);
- Value *RHS = Op1Match ? OpConst : BO->getOperand(1);
- if (auto *C = dyn_cast_or_null<ConstantInt>(
- SimplifyBinOp(BO->getOpcode(), LHS, RHS, DL))) {
- return LVILatticeVal::getRange(ConstantRange(C->getUniqueInteger()));
- }
- }
- return LVILatticeVal::getOverdefined();
-}
-
/// \brief Compute the value of Val on the edge BBFrom -> BBTo. Returns false if
/// Val is not constrained on the edge. Result is unspecified if return value
/// is false.
@@ -1416,11 +1370,10 @@ static bool getEdgeValueLocal(Value *Val, BasicBlock *BBFrom,
bool isTrueDest = BI->getSuccessor(0) == BBTo;
assert(BI->getSuccessor(!isTrueDest) == BBTo &&
"BBTo isn't a successor of BBFrom");
- Value *Condition = BI->getCondition();
// If V is the condition of the branch itself, then we know exactly what
// it is.
- if (Condition == Val) {
+ if (BI->getCondition() == Val) {
Result = LVILatticeVal::get(ConstantInt::get(
Type::getInt1Ty(Val->getContext()), isTrueDest));
return true;
@@ -1428,44 +1381,7 @@ static bool getEdgeValueLocal(Value *Val, BasicBlock *BBFrom,
// If the condition of the branch is an equality comparison, we may be
// able to infer the value.
- Result = getValueFromCondition(Val, Condition, isTrueDest);
- if (!Result.isOverdefined())
- return true;
-
- if (User *Usr = dyn_cast<User>(Val)) {
- assert(Result.isOverdefined() && "Result isn't overdefined");
- if (isa<IntegerType>(Val->getType())) {
- const DataLayout &DL = BBTo->getModule()->getDataLayout();
- if (usesOperand(Usr, Condition)) {
- // If Val has Condition as an operand and Val can be folded into a
- // constant with either Condition == true or Condition == false,
- // propagate the constant.
- // eg.
- // ; %Val is true on the edge to %then.
- // %Val = and i1 %Condition, true.
- // br %Condition, label %then, label %else
- APInt ConditionVal(1, isTrueDest ? 1 : 0);
- Result = constantFoldUser(Val, Condition, ConditionVal, DL);
- } else {
- // If one of Val's operand has an inferred value, we may be able to
- // infer the value of Val.
- // eg.
- // ; %Val is 94 on the edge to %then.
- // %Val = add i8 %Op, 1
- // %Condition = icmp eq i8 %Op, 93
- // br i1 %Condition, label %then, label %else
- for (unsigned i = 0; i < Usr->getNumOperands(); ++i) {
- Value *Op = Usr->getOperand(i);
- LVILatticeVal OpLatticeVal =
- getValueFromCondition(Op, Condition, isTrueDest);
- if (Optional<APInt> OpConst = OpLatticeVal.asConstantInteger()) {
- Result = constantFoldUser(Val, Op, OpConst.getValue(), DL);
- break;
- }
- }
- }
- }
- }
+ Result = getValueFromCondition(Val, BI->getCondition(), isTrueDest);
if (!Result.isOverdefined())
return true;
}
@@ -1474,35 +1390,15 @@ static bool getEdgeValueLocal(Value *Val, BasicBlock *BBFrom,
// If the edge was formed by a switch on the value, then we may know exactly
// what it is.
if (SwitchInst *SI = dyn_cast<SwitchInst>(BBFrom->getTerminator())) {
- Value *Condition = SI->getCondition();
- if (!isa<IntegerType>(Val->getType()))
+ if (SI->getCondition() != Val)
return false;
- bool ValUsesCondition = false;
- if (Condition != Val) {
- // Check if Val has Condition as an operand.
- if (User *Usr = dyn_cast<User>(Val))
- ValUsesCondition = usesOperand(Usr, Condition);
- if (!ValUsesCondition)
- return false;
- }
- assert((Condition == Val || ValUsesCondition) &&
- "Condition != Val nor Val doesn't use Condition");
bool DefaultCase = SI->getDefaultDest() == BBTo;
unsigned BitWidth = Val->getType()->getIntegerBitWidth();
ConstantRange EdgesVals(BitWidth, DefaultCase/*isFullSet*/);
for (auto Case : SI->cases()) {
- APInt CaseValue = Case.getCaseValue()->getValue();
- ConstantRange EdgeVal(CaseValue);
- if (ValUsesCondition) {
- const DataLayout &DL = BBTo->getModule()->getDataLayout();
- LVILatticeVal EdgeLatticeVal =
- constantFoldUser(Val, Condition, CaseValue, DL);
- if (EdgeLatticeVal.isOverdefined())
- return false;
- EdgeVal = EdgeLatticeVal.getConstantRange();
- }
+ ConstantRange EdgeVal(Case.getCaseValue()->getValue());
if (DefaultCase) {
// It is possible that the default destination is the destination of
// some cases. There is no need to perform difference for those cases.
OpenPOWER on IntegriCloud