diff options
| author | Artur Pilipenko <apilipenko@azulsystems.com> | 2016-08-09 09:41:34 +0000 | 
|---|---|---|
| committer | Artur Pilipenko <apilipenko@azulsystems.com> | 2016-08-09 09:41:34 +0000 | 
| commit | a410d81f64a89ec2a0d43773b326d2b820ac0357 (patch) | |
| tree | c643fd8986e30cefc2ecbec5193ba06e4d4998be /llvm/lib/Analysis | |
| parent | 54c32ddf558030dc571ba6809944a1240b663d11 (diff) | |
| download | bcm5719-llvm-a410d81f64a89ec2a0d43773b326d2b820ac0357.tar.gz bcm5719-llvm-a410d81f64a89ec2a0d43773b326d2b820ac0357.zip | |
Teach CorrelatedValuePropagation to mark adds as no wrap
Use LVI to prove that adds do not wrap. The change is motivated by https://llvm.org/bugs/show_bug.cgi?id=28620 bug and it's the first step to fix that problem.
Reviewed By: sanjoy
Differential Revision: http://reviews.llvm.org/D23059
llvm-svn: 278107
Diffstat (limited to 'llvm/lib/Analysis')
| -rw-r--r-- | llvm/lib/Analysis/LazyValueInfo.cpp | 52 | 
1 files changed, 33 insertions, 19 deletions
| diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index 2728687a31c..e6c375a8d8c 100644 --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -1197,30 +1197,44 @@ bool getValueFromCondition(Value *Val, Value *Cond, LVILatticeVal &Result,          Result = LVILatticeVal::getNot(cast<Constant>(RHS));        return true;      } +  } -    // Recognize the range checking idiom that InstCombine produces. -    // (X+C1) u< C2 --> [-C1, C2-C1) -    ConstantInt *Offset = nullptr; -    if (Predicate == ICmpInst::ICMP_ULT) -      match(LHS, m_Add(m_Specific(Val), m_ConstantInt(Offset))); +  // Use ConstantRange::makeAllowedICmpRegion in order to determine the possible +  // range of Val guaranteed by the condition. Recognize comparisons in the from +  // of: +  //  icmp <pred> Val, ... +  //  icmp ult (add Val, Offset), ... +  // The latter is the range checking idiom that InstCombine produces. Subtract +  // the offset from the allowed range for RHS in this case. + +  // Val or (add Val, Offset) can be on either hand of the comparison +  if (LHS != Val && !match(LHS, m_Add(m_Specific(Val), m_ConstantInt()))) { +    std::swap(LHS, RHS); +    Predicate = CmpInst::getSwappedPredicate(Predicate); +  } -    ConstantInt *CI = dyn_cast<ConstantInt>(RHS); -    if (CI && (LHS == Val || Offset)) { -      // Calculate the range of values that are allowed by the comparison -      ConstantRange CmpRange(CI->getValue()); +  ConstantInt *Offset = nullptr; +  if (Predicate == ICmpInst::ICMP_ULT) +    match(LHS, m_Add(m_Specific(Val), m_ConstantInt(Offset))); -      // If we're interested in the false dest, invert the condition -      CmpInst::Predicate Pred = -          isTrueDest ? Predicate : CmpInst::getInversePredicate(Predicate); -      ConstantRange TrueValues = -          ConstantRange::makeAllowedICmpRegion(Pred, CmpRange); +  if (LHS == Val || Offset) { +    // Calculate the range of values that are allowed by the comparison +    ConstantRange RHSRange(RHS->getType()->getIntegerBitWidth(), +                           /*isFullSet=*/true); +    if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) +      RHSRange = ConstantRange(CI->getValue()); -      if (Offset) // Apply the offset from above. -        TrueValues = TrueValues.subtract(Offset->getValue()); +    // If we're interested in the false dest, invert the condition +    CmpInst::Predicate Pred = +            isTrueDest ? Predicate : CmpInst::getInversePredicate(Predicate); +    ConstantRange TrueValues = +            ConstantRange::makeAllowedICmpRegion(Pred, RHSRange); -      Result = LVILatticeVal::getRange(std::move(TrueValues)); -      return true; -    } +    if (Offset) // Apply the offset from above. +      TrueValues = TrueValues.subtract(Offset->getValue()); + +    Result = LVILatticeVal::getRange(std::move(TrueValues)); +    return true;    }    return false; | 

