Пример #1
0
static bool processAdd(BinaryOperator *AddOp, LazyValueInfo *LVI) {
  typedef OverflowingBinaryOperator OBO;

  if (DontProcessAdds)
    return false;

  if (AddOp->getType()->isVectorTy() || hasLocalDefs(AddOp))
    return false;

  bool NSW = AddOp->hasNoSignedWrap();
  bool NUW = AddOp->hasNoUnsignedWrap();
  if (NSW && NUW)
    return false;

  BasicBlock *BB = AddOp->getParent();

  Value *LHS = AddOp->getOperand(0);
  Value *RHS = AddOp->getOperand(1);

  ConstantRange LRange = LVI->getConstantRange(LHS, BB, AddOp);

  // Initialize RRange only if we need it. If we know that guaranteed no wrap
  // range for the given LHS range is empty don't spend time calculating the
  // range for the RHS.
  Optional<ConstantRange> RRange;
  auto LazyRRange = [&] () {
      if (!RRange)
        RRange = LVI->getConstantRange(RHS, BB, AddOp);
      return RRange.getValue();
  };

  bool Changed = false;
  if (!NUW) {
    ConstantRange NUWRange =
            LRange.makeGuaranteedNoWrapRegion(BinaryOperator::Add, LRange,
                                              OBO::NoUnsignedWrap);
    if (!NUWRange.isEmptySet()) {
      bool NewNUW = NUWRange.contains(LazyRRange());
      AddOp->setHasNoUnsignedWrap(NewNUW);
      Changed |= NewNUW;
    }
  }
  if (!NSW) {
    ConstantRange NSWRange =
            LRange.makeGuaranteedNoWrapRegion(BinaryOperator::Add, LRange,
                                              OBO::NoSignedWrap);
    if (!NSWRange.isEmptySet()) {
      bool NewNSW = NSWRange.contains(LazyRRange());
      AddOp->setHasNoSignedWrap(NewNSW);
      Changed |= NewNSW;
    }
  }

  return Changed;
}
Пример #2
0
TEST(InterpreterTests, KBCRReduction) {
  ConstantRange CR(WIDTH, /*isFullSet=*/false);
  KnownBits KB(WIDTH);
  do {
    do {
      KnownBits CalculatedKB = KB;
      ConstantRange CalculatedCR = CR;
      improveKBCR(CalculatedKB, CalculatedCR);

      KnownBits ExhaustiveKB = KB;
      ConstantRange ExhaustiveCR = CR;
      TestingUtil::exhaustiveKBCRReduction(ExhaustiveKB, ExhaustiveCR);

      if (KnownBitsAnalysis::isConflictingKB(CalculatedKB, ExhaustiveKB)) {
	outs() << "Unsound!! CR KB reduction for KB\n";
	outs() << "Original KB: " << KnownBitsAnalysis::knownBitsString(KB) << "\n";
	outs() << "Original CR: " << CR << "\n";
	outs() << "CalculatedKB: " << KnownBitsAnalysis::knownBitsString(CalculatedKB) << '\n';
	outs() << "ExhaustiveKB: " << KnownBitsAnalysis::knownBitsString(ExhaustiveKB) << '\n';
	ASSERT_TRUE(false);
      }

      if (!CalculatedCR.contains(ExhaustiveCR)) {
	outs() << "Unsound!! CR KB reduction for CR\n";
	outs() << "Original KB: " << KnownBitsAnalysis::knownBitsString(KB) << "\n";
	outs() << "Original CR: " << CR << "\n";
	outs() << "CalculatedCR: " << CalculatedCR << '\n';
	outs() << "ExhaustiveCR: " << ExhaustiveCR << '\n';
	ASSERT_TRUE(false);
      }

      CR = CRTesting::nextCR(CR);
    } while(!CR.isEmptySet());
  } while(KBTesting::nextKB(KB));
}
// See if we can prove that the given overflow intrinsic will not overflow.
static bool willNotOverflow(IntrinsicInst *II, LazyValueInfo *LVI) {
  using OBO = OverflowingBinaryOperator;
  auto NoWrap = [&] (Instruction::BinaryOps BinOp, unsigned NoWrapKind) {
    Value *RHS = II->getOperand(1);
    ConstantRange RRange = LVI->getConstantRange(RHS, II->getParent(), II);
    ConstantRange NWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
        BinOp, RRange, NoWrapKind);
    // As an optimization, do not compute LRange if we do not need it.
    if (NWRegion.isEmptySet())
      return false;
    Value *LHS = II->getOperand(0);
    ConstantRange LRange = LVI->getConstantRange(LHS, II->getParent(), II);
    return NWRegion.contains(LRange);
  };
  switch (II->getIntrinsicID()) {
  default:
    break;
  case Intrinsic::uadd_with_overflow:
    return NoWrap(Instruction::Add, OBO::NoUnsignedWrap);
  case Intrinsic::sadd_with_overflow:
    return NoWrap(Instruction::Add, OBO::NoSignedWrap);
  case Intrinsic::usub_with_overflow:
    return NoWrap(Instruction::Sub, OBO::NoUnsignedWrap);
  case Intrinsic::ssub_with_overflow:
    return NoWrap(Instruction::Sub, OBO::NoSignedWrap);
  }
  return false;
}
Пример #4
0
/// getPredicateOnEdge - Determine whether the specified value comparison
/// with a constant is known to be true or false on the specified CFG edge.
/// Pred is a CmpInst predicate.
LazyValueInfo::Tristate
LazyValueInfo::getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
                                  BasicBlock *FromBB, BasicBlock *ToBB) {
  LVILatticeVal Result = getCache(PImpl).getValueOnEdge(V, FromBB, ToBB);
  
  // If we know the value is a constant, evaluate the conditional.
  Constant *Res = 0;
  if (Result.isConstant()) {
    Res = ConstantFoldCompareInstOperands(Pred, Result.getConstant(), C, TD,
                                          TLI);
    if (ConstantInt *ResCI = dyn_cast<ConstantInt>(Res))
      return ResCI->isZero() ? False : True;
    return Unknown;
  }
  
  if (Result.isConstantRange()) {
    ConstantInt *CI = dyn_cast<ConstantInt>(C);
    if (!CI) return Unknown;
    
    ConstantRange CR = Result.getConstantRange();
    if (Pred == ICmpInst::ICMP_EQ) {
      if (!CR.contains(CI->getValue()))
        return False;
      
      if (CR.isSingleElement() && CR.contains(CI->getValue()))
        return True;
    } else if (Pred == ICmpInst::ICMP_NE) {
      if (!CR.contains(CI->getValue()))
        return True;
      
      if (CR.isSingleElement() && CR.contains(CI->getValue()))
        return False;
    }
    
    // Handle more complex predicates.
    ConstantRange TrueValues =
        ICmpInst::makeConstantRange((ICmpInst::Predicate)Pred, CI->getValue());
    if (TrueValues.contains(CR))
      return True;
    if (TrueValues.inverse().contains(CR))
      return False;
    return Unknown;
  }
  
  if (Result.isNotConstant()) {
    // If this is an equality comparison, we can try to fold it knowing that
    // "V != C1".
    if (Pred == ICmpInst::ICMP_EQ) {
      // !C1 == C -> false iff C1 == C.
      Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE,
                                            Result.getNotConstant(), C, TD,
                                            TLI);
      if (Res->isNullValue())
        return False;
    } else if (Pred == ICmpInst::ICMP_NE) {
      // !C1 != C -> true iff C1 == C.
      Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE,
                                            Result.getNotConstant(), C, TD,
                                            TLI);
      if (Res->isNullValue())
        return True;
    }
    return Unknown;
  }
  
  return Unknown;
}
Пример #5
0
static LazyValueInfo::Tristate
getPredicateResult(unsigned Pred, Constant *C, LVILatticeVal &Result,
                   const DataLayout *DL, TargetLibraryInfo *TLI) {

  // If we know the value is a constant, evaluate the conditional.
  Constant *Res = nullptr;
  if (Result.isConstant()) {
    Res = ConstantFoldCompareInstOperands(Pred, Result.getConstant(), C, DL,
                                          TLI);
    if (ConstantInt *ResCI = dyn_cast<ConstantInt>(Res))
      return ResCI->isZero() ? LazyValueInfo::False : LazyValueInfo::True;
    return LazyValueInfo::Unknown;
  }

  if (Result.isConstantRange()) {
    ConstantInt *CI = dyn_cast<ConstantInt>(C);
    if (!CI) return LazyValueInfo::Unknown;

    ConstantRange CR = Result.getConstantRange();
    if (Pred == ICmpInst::ICMP_EQ) {
      if (!CR.contains(CI->getValue()))
        return LazyValueInfo::False;

      if (CR.isSingleElement() && CR.contains(CI->getValue()))
        return LazyValueInfo::True;
    } else if (Pred == ICmpInst::ICMP_NE) {
      if (!CR.contains(CI->getValue()))
        return LazyValueInfo::True;

      if (CR.isSingleElement() && CR.contains(CI->getValue()))
        return LazyValueInfo::False;
    }

    // Handle more complex predicates.
    ConstantRange TrueValues =
        ICmpInst::makeConstantRange((ICmpInst::Predicate)Pred, CI->getValue());
    if (TrueValues.contains(CR))
      return LazyValueInfo::True;
    if (TrueValues.inverse().contains(CR))
      return LazyValueInfo::False;
    return LazyValueInfo::Unknown;
  }

  if (Result.isNotConstant()) {
    // If this is an equality comparison, we can try to fold it knowing that
    // "V != C1".
    if (Pred == ICmpInst::ICMP_EQ) {
      // !C1 == C -> false iff C1 == C.
      Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE,
                                            Result.getNotConstant(), C, DL,
                                            TLI);
      if (Res->isNullValue())
        return LazyValueInfo::False;
    } else if (Pred == ICmpInst::ICMP_NE) {
      // !C1 != C -> true iff C1 == C.
      Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE,
                                            Result.getNotConstant(), C, DL,
                                            TLI);
      if (Res->isNullValue())
        return LazyValueInfo::True;
    }
    return LazyValueInfo::Unknown;
  }

  return LazyValueInfo::Unknown;
}