[PATCH] D60656: [LVI][CVP] Calculate with.overflow result range

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri May 10 13:18:50 PDT 2019


nikic added a comment.

@spatel What do you think about going for the following abstraction instead? What I have in mind here is to make this also reusable for operations other than `binaryOp()`, such as `uadd_sat()` and friends.

  diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
  index e7ca69150c0..126a3359ea4 100644
  --- a/llvm/lib/Analysis/LazyValueInfo.cpp
  +++ b/llvm/lib/Analysis/LazyValueInfo.cpp
  @@ -422,6 +422,10 @@ namespace {
                                BasicBlock *BB);
     Optional<ConstantRange> getRangeForOperand(unsigned Op, Instruction *I,
                                                BasicBlock *BB);
  +  bool solveBlockValueBinaryOpImpl(
  +      ValueLatticeElement &BBLV, Instruction *I, BasicBlock *BB,
  +      std::function<ConstantRange(const ConstantRange &,
  +                                  const ConstantRange &)> OpFn);
     bool solveBlockValueBinaryOp(ValueLatticeElement &BBLV, BinaryOperator *BBI,
                                  BasicBlock *BB);
     bool solveBlockValueCast(ValueLatticeElement &BBLV, CastInst *CI,
  @@ -1019,6 +1023,26 @@ bool LazyValueInfoImpl::solveBlockValueCast(ValueLatticeElement &BBLV,
     return true;
   }
   
  +bool LazyValueInfoImpl::solveBlockValueBinaryOpImpl(
  +    ValueLatticeElement &BBLV, Instruction *I, BasicBlock *BB,
  +    std::function<ConstantRange(const ConstantRange &,
  +                                const ConstantRange &)> OpFn) {
  +  // Figure out the ranges of the operands.  If that fails, use a
  +  // conservative range, but apply the transfer rule anyways.  This
  +  // lets us pick up facts from expressions like "and i32 (call i32
  +  // @foo()), 32"
  +  Optional<ConstantRange> LHSRes = getRangeForOperand(0, I, BB);
  +  Optional<ConstantRange> RHSRes = getRangeForOperand(1, I, BB);
  +  if (!LHSRes.hasValue() || !RHSRes.hasValue())
  +    // More work to do before applying this transfer rule.
  +    return false;
  +
  +  ConstantRange LHSRange = LHSRes.getValue();
  +  ConstantRange RHSRange = RHSRes.getValue();
  +  BBLV = ValueLatticeElement::getRange(OpFn(LHSRange, RHSRange));
  +  return true;
  +}
  +
   bool LazyValueInfoImpl::solveBlockValueBinaryOp(ValueLatticeElement &BBLV,
                                                   BinaryOperator *BO,
                                                   BasicBlock *BB) {
  @@ -1039,8 +1063,10 @@ bool LazyValueInfoImpl::solveBlockValueBinaryOp(ValueLatticeElement &BBLV,
     case Instruction::AShr:
     case Instruction::And:
     case Instruction::Or:
  -    // continue into the code below
  -    break;
  +    return solveBlockValueBinaryOpImpl(BBLV, BO, BB,
  +        [&](const ConstantRange &CR1, const ConstantRange &CR2) {
  +          return CR1.binaryOp(BO->getOpcode(), CR2);
  +        });
     default:
       // Unhandled instructions are overdefined.
       LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName()
  @@ -1048,27 +1074,6 @@ bool LazyValueInfoImpl::solveBlockValueBinaryOp(ValueLatticeElement &BBLV,
       BBLV = ValueLatticeElement::getOverdefined();
       return true;
     };
  -
  -  // Figure out the ranges of the operands.  If that fails, use a
  -  // conservative range, but apply the transfer rule anyways.  This
  -  // lets us pick up facts from expressions like "and i32 (call i32
  -  // @foo()), 32"
  -  Optional<ConstantRange> LHSRes = getRangeForOperand(0, BO, BB);
  -  Optional<ConstantRange> RHSRes = getRangeForOperand(1, BO, BB);
  -
  -  if (!LHSRes.hasValue() || !RHSRes.hasValue())
  -    // More work to do before applying this transfer rule.
  -    return false;
  -
  -  ConstantRange LHSRange = LHSRes.getValue();
  -  ConstantRange RHSRange = RHSRes.getValue();
  -
  -  // NOTE: We're currently limited by the set of operations that ConstantRange
  -  // can evaluate symbolically.  Enhancing that set will allows us to analyze
  -  // more definitions.
  -  Instruction::BinaryOps BinOp = BO->getOpcode();
  -  BBLV = ValueLatticeElement::getRange(LHSRange.binaryOp(BinOp, RHSRange));
  -  return true;
   }
   
   static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI,


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60656/new/

https://reviews.llvm.org/D60656





More information about the llvm-commits mailing list