summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/InstructionSimplify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp38
1 files changed, 24 insertions, 14 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 8c48174b9f52..ce651783caf1 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3729,6 +3729,26 @@ static Value *simplifyICmpWithIntrinsicOnLHS(CmpInst::Predicate Pred,
}
}
+/// Helper method to get range from metadata or attribute.
+static std::optional<ConstantRange> getRange(Value *V,
+ const InstrInfoQuery &IIQ) {
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ if (MDNode *MD = IIQ.getMetadata(I, LLVMContext::MD_range))
+ return getConstantRangeFromMetadata(*MD);
+
+ Attribute Range;
+ if (const Argument *A = dyn_cast<Argument>(V)) {
+ Range = A->getAttribute(llvm::Attribute::Range);
+ } else if (const CallBase *CB = dyn_cast<CallBase>(V)) {
+ Range = CB->getRetAttr(llvm::Attribute::Range);
+ }
+
+ if (Range.isValid())
+ return Range.getRange();
+
+ return std::nullopt;
+}
+
/// Given operands for an ICmpInst, see if we can fold the result.
/// If not, this returns null.
static Value *simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
@@ -3776,24 +3796,14 @@ static Value *simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
// If both operands have range metadata, use the metadata
// to simplify the comparison.
- if (isa<Instruction>(RHS) && isa<Instruction>(LHS)) {
- auto RHS_Instr = cast<Instruction>(RHS);
- auto LHS_Instr = cast<Instruction>(LHS);
-
- if (Q.IIQ.getMetadata(RHS_Instr, LLVMContext::MD_range) &&
- Q.IIQ.getMetadata(LHS_Instr, LLVMContext::MD_range)) {
- auto RHS_CR = getConstantRangeFromMetadata(
- *RHS_Instr->getMetadata(LLVMContext::MD_range));
- auto LHS_CR = getConstantRangeFromMetadata(
- *LHS_Instr->getMetadata(LLVMContext::MD_range));
-
- if (LHS_CR.icmp(Pred, RHS_CR))
+ if (std::optional<ConstantRange> RhsCr = getRange(RHS, Q.IIQ))
+ if (std::optional<ConstantRange> LhsCr = getRange(LHS, Q.IIQ)) {
+ if (LhsCr->icmp(Pred, *RhsCr))
return ConstantInt::getTrue(ITy);
- if (LHS_CR.icmp(CmpInst::getInversePredicate(Pred), RHS_CR))
+ if (LhsCr->icmp(CmpInst::getInversePredicate(Pred), *RhsCr))
return ConstantInt::getFalse(ITy);
}
- }
// Compare of cast, for example (zext X) != 0 -> X != 0
if (isa<CastInst>(LHS) && (isa<Constant>(RHS) || isa<CastInst>(RHS))) {