Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 7 additions & 20 deletions llvm/lib/Analysis/InstructionSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2686,27 +2686,14 @@ static Constant *computePointerICmp(CmpPredicate Pred, Value *LHS, Value *RHS,
const DataLayout &DL = Q.DL;
const TargetLibraryInfo *TLI = Q.TLI;

// We can only fold certain predicates on pointer comparisons.
switch (Pred) {
default:
// We fold equality and unsigned predicates on pointer comparisons, but forbid
// signed predicates since a GEP with inbounds could cross the sign boundary.
if (CmpInst::isSigned(Pred))
return nullptr;

// Equality comparisons are easy to fold.
case CmpInst::ICMP_EQ:
case CmpInst::ICMP_NE:
break;

// We can only handle unsigned relational comparisons because 'inbounds' on
// a GEP only protects against unsigned wrapping.
case CmpInst::ICMP_UGT:
case CmpInst::ICMP_UGE:
case CmpInst::ICMP_ULT:
case CmpInst::ICMP_ULE:
// However, we have to switch them to their signed variants to handle
// negative indices from the base pointer.
Pred = ICmpInst::getSignedPredicate(Pred);
break;
}
// We have to switch to a signed predicate to handle negative indices from
// the base pointer.
Pred = ICmpInst::getSignedPredicate(Pred);

// Strip off any constant offsets so that we can reason about them.
// It's tempting to use getUnderlyingObject or even just stripInBoundsOffsets
Expand All @@ -2730,7 +2717,7 @@ static Constant *computePointerICmp(CmpPredicate Pred, Value *LHS, Value *RHS,
ICmpInst::compare(LHSOffset, RHSOffset, Pred));

// Various optimizations for (in)equality comparisons.
if (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE) {
if (ICmpInst::isEquality(Pred)) {
// Different non-empty allocations that exist at the same time have
// different addresses (if the program can tell). If the offsets are
// within the bounds of their allocations (and not one-past-the-end!
Expand Down