diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 3cbc4107433ef..59002cd934ab1 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -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 @@ -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!