diff options
author | Daniel Jasper <djasper@google.com> | 2017-08-01 05:30:49 +0000 |
---|---|---|
committer | Daniel Jasper <djasper@google.com> | 2017-08-01 05:30:49 +0000 |
commit | 43cd2ef49c843c0478569dfdb375d7c30ad0012a (patch) | |
tree | a7925fcb58c7f192a2e570b29e076146a25e5ec7 /llvm/lib/Analysis/LazyValueInfo.cpp | |
parent | 8882ac2ac911e6a4478ca516ce345fa8339ef9d9 (diff) | |
download | bcm5719-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.cpp | 112 |
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. |