From f94bbe19b6f6086ff94b1eb4ef0bc5802752bfe1 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 20 Sep 2020 20:46:51 +0200 Subject: [PATCH] [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. --- llvm/lib/Analysis/LazyValueInfo.cpp | 48 ++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index d597d45..4e9505a 100644 --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -1096,6 +1096,26 @@ static bool matchICmpOperand(const APInt *&Offset, Value *LHS, Value *Val, 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(RHS)) + RHSRange = ConstantRange(CI->getValue()); + else if (Instruction *I = dyn_cast(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, bool isTrueDest) { Value *LHS = ICI->getOperand(0); @@ -1118,30 +1138,14 @@ static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI, return ValueLatticeElement::getOverdefined(); const APInt *Offset = nullptr; - if (!matchICmpOperand(Offset, LHS, Val, EdgePred)) { - std::swap(LHS, RHS); - EdgePred = CmpInst::getSwappedPredicate(EdgePred); - if (!matchICmpOperand(Offset, LHS, Val, EdgePred)) - return ValueLatticeElement::getOverdefined(); - } - - // Calculate the range of values that are allowed by the comparison. - ConstantRange RHSRange(RHS->getType()->getIntegerBitWidth(), - /*isFullSet=*/true); - if (ConstantInt *CI = dyn_cast(RHS)) - RHSRange = ConstantRange(CI->getValue()); - else if (Instruction *I = dyn_cast(RHS)) - if (auto *Ranges = I->getMetadata(LLVMContext::MD_range)) - RHSRange = getConstantRangeFromMetadata(*Ranges); + if (matchICmpOperand(Offset, LHS, Val, EdgePred)) + return getValueFromSimpleICmpCondition(EdgePred, RHS, Offset); - // If we're interested in the false dest, invert the condition - ConstantRange TrueValues = - ConstantRange::makeAllowedICmpRegion(EdgePred, RHSRange); + CmpInst::Predicate SwappedPred = CmpInst::getSwappedPredicate(EdgePred); + if (matchICmpOperand(Offset, RHS, Val, SwappedPred)) + return getValueFromSimpleICmpCondition(SwappedPred, LHS, Offset); - if (Offset) // Apply the offset from above. - TrueValues = TrueValues.subtract(*Offset); - - return ValueLatticeElement::getRange(std::move(TrueValues)); + return ValueLatticeElement::getOverdefined(); } // Handle conditions of the form -- 2.7.4