diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 1261664c5b986..1b4260785159f 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -93,7 +93,7 @@ static cl::opt DomConditionsMaxUses("dom-conditions-max-uses", /// Maximum number of instructions to check between assume and context /// instruction. -static constexpr unsigned MaxInstrsToCheckForFree = 16; +static constexpr unsigned MaxInstrsToCheckForFree = 32; /// Returns the bitwidth of the given scalar or pointer type. For vector types, /// returns the element type's bitwidth. @@ -704,9 +704,10 @@ bool llvm::isValidAssumeForContext(const Instruction *Inv, bool llvm::willNotFreeBetween(const Instruction *Assume, const Instruction *CtxI) { // Helper to check if there are any calls in the range that may free memory. - auto hasNoFreeInRange = [](auto Range) { - for (const auto &[Idx, I] : enumerate(Range)) { - if (Idx > MaxInstrsToCheckForFree) + unsigned NumChecked = 0; + auto hasNoFreeInRange = [&NumChecked](auto Range) { + for (const Instruction &I : Range) { + if (NumChecked++ > MaxInstrsToCheckForFree) return false; if (auto *CB = dyn_cast(&I)) { @@ -718,27 +719,32 @@ bool llvm::willNotFreeBetween(const Instruction *Assume, return true; }; - // Handle cross-block case: CtxI in a successor of Assume's block. const BasicBlock *CtxBB = CtxI->getParent(); const BasicBlock *AssumeBB = Assume->getParent(); BasicBlock::const_iterator CtxIter = CtxI->getIterator(); - if (CtxBB != AssumeBB) { - if (CtxBB->getSinglePredecessor() != AssumeBB) + if (CtxBB == AssumeBB) { + // Same block case: check that Assume comes before CtxI. + if (Assume != CtxI && !Assume->comesBefore(CtxI)) return false; + return hasNoFreeInRange(make_range(Assume->getIterator(), CtxIter)); + } + + // Handle chain of single-predecessor blocks. + const BasicBlock *CurBB = CtxBB; + while (true) { + if (CurBB == AssumeBB) + return hasNoFreeInRange( + make_range(Assume->getIterator(), AssumeBB->end())); - if (!hasNoFreeInRange(make_range(CtxBB->begin(), CtxIter))) + const BasicBlock *PredBB = CurBB->getSinglePredecessor(); + if (!PredBB) return false; - CtxIter = AssumeBB->end(); - } else { - // Same block case: check that Assume comes before CtxI. - if (Assume != CtxI && !Assume->comesBefore(CtxI)) + if (!hasNoFreeInRange(make_range(CurBB->begin(), + CurBB == CtxBB ? CtxIter : CurBB->end()))) return false; + CurBB = PredBB; } - - // Check if there are any calls between Assume and CtxIter that may free - // memory. - return hasNoFreeInRange(make_range(Assume->getIterator(), CtxIter)); } // TODO: cmpExcludesZero misses many cases where `RHS` is non-constant but diff --git a/llvm/test/Transforms/LICM/hoist-deref-load.ll b/llvm/test/Transforms/LICM/hoist-deref-load.ll index c498e85ddd6c2..4ff21a34afa3b 100644 --- a/llvm/test/Transforms/LICM/hoist-deref-load.ll +++ b/llvm/test/Transforms/LICM/hoist-deref-load.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -passes=licm -verify-memoryssa < %s | FileCheck %s +; RUN: opt -S -passes=licm -verify-memoryssa -use-dereferenceable-at-point-semantics < %s | FileCheck %s ; RUN: opt -aa-pipeline=basic-aa -passes='require,loop-mssa(loop-simplifycfg,licm)' -verify-memoryssa -S < %s | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/llvm/test/Transforms/SLPVectorizer/AArch64/masked-loads-side-effects-after-vec.ll b/llvm/test/Transforms/SLPVectorizer/AArch64/masked-loads-side-effects-after-vec.ll index ca3c8bbac6366..df4c527aa216a 100644 --- a/llvm/test/Transforms/SLPVectorizer/AArch64/masked-loads-side-effects-after-vec.ll +++ b/llvm/test/Transforms/SLPVectorizer/AArch64/masked-loads-side-effects-after-vec.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt -S --passes=slp-vectorizer -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s +; RUN: opt -S --passes=slp-vectorizer -mtriple=aarch64-unknown-linux-gnu -use-dereferenceable-at-point-semantics < %s | FileCheck %s declare noalias ptr @malloc()