[llvm] [ValueTracking] isNonZero trunc of sub of ptr2int's with recursive GEP where pointers are limited to a 32bit alloc. (PR #84933)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 24 18:22:39 PDT 2024
================
@@ -910,6 +916,67 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
Changed = true;
}
+ // Handle scenarios like trunc i64 (sub(ptr2int, ptr2int)) to i32 / trunc i64
+ // (lshr(sub(ptr2int, ptr2int))) to i32, where the ptrs are from same object
+ // and one of the pointers is a recursive GEP. And either the objectSize is
+ // known OR is indicative via a compiler flag, which suggests objectSize<4G.
+
+ // Check if trunc src type is same as Ptr type and dest is a 32bit.
+ if (!Trunc.hasNoUnsignedWrap() && SrcWidth == DL.getPointerSizeInBits() &&
+ DestTy == Type::getInt32Ty(Trunc.getContext())) {
+ Value *A, *B;
+ if (match(Src, m_Sub(m_PtrToIntSameSize(DL, m_Value(A)),
+ m_PtrToIntSameSize(DL, m_Value(B)))) ||
+ match(Src, m_LShr(m_Sub(m_PtrToIntSameSize(DL, m_Value(A)),
+ m_PtrToIntSameSize(DL, m_Value(B))),
+ m_ConstantInt()))) {
+ // Check for a specific pattern where A is recursive GEP with a PHI ptr
+ // with incoming values as (Start,Step) and Start==B.
+ auto *GEPA = dyn_cast<GEPOperator>(A);
+ if (!GEPA) {
+ GEPA = dyn_cast<GEPOperator>(B);
+ std::swap(A, B);
+ }
----------------
nikic wrote:
Don't you need inbounds for this (please also add test)? Otherwise the GEPs may go beyond the limit of the allocation size.
https://github.com/llvm/llvm-project/pull/84933
More information about the llvm-commits
mailing list