[LVI] Refactor getValueFromICmpCondition (NFC)

Rewrite this in a way where the core logic is in a separate
function, that is invoked with swapped operands. This makes it
easier to add handling for additional icmp patterns.
This commit is contained in:
Nikita Popov 2020-09-20 20:46:51 +02:00
parent 0bfeede669
commit f94bbe19b6
1 changed files with 26 additions and 22 deletions

View File

@ -1096,6 +1096,26 @@ static bool matchICmpOperand(const APInt *&Offset, Value *LHS, Value *Val,
return false; return false;
} }
/// Get value range for a "(Val + Offset) Pred RHS" condition.
static ValueLatticeElement getValueFromSimpleICmpCondition(
CmpInst::Predicate Pred, Value *RHS, const APInt *Offset) {
ConstantRange RHSRange(RHS->getType()->getIntegerBitWidth(),
/*isFullSet=*/true);
if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
RHSRange = ConstantRange(CI->getValue());
else if (Instruction *I = dyn_cast<Instruction>(RHS))
if (auto *Ranges = I->getMetadata(LLVMContext::MD_range))
RHSRange = getConstantRangeFromMetadata(*Ranges);
ConstantRange TrueValues =
ConstantRange::makeAllowedICmpRegion(Pred, RHSRange);
if (Offset)
TrueValues = TrueValues.subtract(*Offset);
return ValueLatticeElement::getRange(std::move(TrueValues));
}
static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI, static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI,
bool isTrueDest) { bool isTrueDest) {
Value *LHS = ICI->getOperand(0); Value *LHS = ICI->getOperand(0);
@ -1118,30 +1138,14 @@ static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI,
return ValueLatticeElement::getOverdefined(); return ValueLatticeElement::getOverdefined();
const APInt *Offset = nullptr; const APInt *Offset = nullptr;
if (!matchICmpOperand(Offset, LHS, Val, EdgePred)) { if (matchICmpOperand(Offset, LHS, Val, EdgePred))
std::swap(LHS, RHS); return getValueFromSimpleICmpCondition(EdgePred, RHS, Offset);
EdgePred = CmpInst::getSwappedPredicate(EdgePred);
if (!matchICmpOperand(Offset, LHS, Val, EdgePred))
return ValueLatticeElement::getOverdefined();
}
// Calculate the range of values that are allowed by the comparison. CmpInst::Predicate SwappedPred = CmpInst::getSwappedPredicate(EdgePred);
ConstantRange RHSRange(RHS->getType()->getIntegerBitWidth(), if (matchICmpOperand(Offset, RHS, Val, SwappedPred))
/*isFullSet=*/true); return getValueFromSimpleICmpCondition(SwappedPred, LHS, Offset);
if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
RHSRange = ConstantRange(CI->getValue());
else if (Instruction *I = dyn_cast<Instruction>(RHS))
if (auto *Ranges = I->getMetadata(LLVMContext::MD_range))
RHSRange = getConstantRangeFromMetadata(*Ranges);
// If we're interested in the false dest, invert the condition return ValueLatticeElement::getOverdefined();
ConstantRange TrueValues =
ConstantRange::makeAllowedICmpRegion(EdgePred, RHSRange);
if (Offset) // Apply the offset from above.
TrueValues = TrueValues.subtract(*Offset);
return ValueLatticeElement::getRange(std::move(TrueValues));
} }
// Handle conditions of the form // Handle conditions of the form