diff options
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 38 |
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))) { |