[llvm] [LAA] Don't check for free in evaluatePtrAddRecAtMaxBTCWillNotWrap() (PR #202341)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 8 07:01:20 PDT 2026
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/202341
The fact that an object of a certain size existed at the the location at some point is sufficient to prove the desired nowrap fact. Whether the object still exists there doesn't matter in this context.
>From 48991606218f2213fee22e1e036a8d6d7b8cf77d Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 8 Jun 2026 15:56:05 +0200
Subject: [PATCH] [LAA] Don't check for free in
evaluatePtrAddRecAtMaxBTCWillNotWrap()
The fact that an object of a certain size existed at the the location
at some point is sufficient to prove the desired nowrap fact.
Whether the object still exists there doesn't matter in this context.
---
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 7 +++----
.../LoopAccessAnalysis/early-exit-runtime-checks.ll | 5 +++--
llvm/test/Transforms/LoopVectorize/early-exit-calls.ll | 1 +
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 60e15b2a5bd82..74f0fa8a954da 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -222,10 +222,12 @@ static bool evaluatePtrAddRecAtMaxBTCWillNotWrap(
const Loop *L = AR->getLoop();
bool CheckForNonNull, CheckForFreed;
Value *StartPtrV = StartPtr->getValue();
+ // We can ignore frees, as the fact that an object of a certain size existed
+ // at the location *at some point* is sufficient to derive the nowrap fact.
uint64_t DerefBytes = StartPtrV->getPointerDereferenceableBytes(
DL, CheckForNonNull, CheckForFreed);
- if (DerefBytes && (CheckForNonNull || CheckForFreed))
+ if (DerefBytes && CheckForNonNull)
return false;
const SCEV *Step = AR->getStepRecurrence(SE);
@@ -243,9 +245,6 @@ static bool evaluatePtrAddRecAtMaxBTCWillNotWrap(
[&](RetainedKnowledge RK, Instruction *Assume, auto) {
if (!isValidAssumeForContext(Assume, CtxI, DT))
return false;
- if (StartPtrV->canBeFreed() &&
- !willNotFreeBetween(Assume, CtxI))
- return false;
DerefRK = std::max(DerefRK, RK);
return true;
});
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/early-exit-runtime-checks.ll b/llvm/test/Analysis/LoopAccessAnalysis/early-exit-runtime-checks.ll
index 05aad8a6118d2..1b9f22c53e1f9 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/early-exit-runtime-checks.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/early-exit-runtime-checks.ll
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s
+; RUN: opt -passes='print<access-info>' -use-dereferenceable-at-point-semantics -disable-output %s 2>&1 | FileCheck %s
define void @all_exits_dominate_latch_countable_exits_at_most_500_iterations_known_deref(ptr dereferenceable(2000) %A, ptr dereferenceable(2000) %B) {
; CHECK-LABEL: 'all_exits_dominate_latch_countable_exits_at_most_500_iterations_known_deref'
@@ -830,10 +831,10 @@ define void @all_exits_dominate_latch_countable_exits_at_most_500_iterations_kno
; CHECK-NEXT: %gep.A = getelementptr inbounds i32, ptr %A, i64 %iv
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group GRP0:
-; CHECK-NEXT: (Low: %B High: inttoptr (i64 -1 to ptr))
+; CHECK-NEXT: (Low: %B High: (2000 + %B))
; CHECK-NEXT: Member: {%B,+,4}<nuw><%loop.header>
; CHECK-NEXT: Group GRP1:
-; CHECK-NEXT: (Low: %A High: inttoptr (i64 -1 to ptr))
+; CHECK-NEXT: (Low: %A High: (2000 + %A))
; CHECK-NEXT: Member: {%A,+,4}<nuw><%loop.header>
; CHECK-EMPTY:
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
diff --git a/llvm/test/Transforms/LoopVectorize/early-exit-calls.ll b/llvm/test/Transforms/LoopVectorize/early-exit-calls.ll
index 29bd33e24309c..5f56f5d797589 100644
--- a/llvm/test/Transforms/LoopVectorize/early-exit-calls.ll
+++ b/llvm/test/Transforms/LoopVectorize/early-exit-calls.ll
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6
; RUN: opt -passes=loop-vectorize -force-vector-width=4 -S %s | FileCheck %s
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 -use-dereferenceable-at-point-semantics -S %s | FileCheck %s
define i32 @early_exit_with_extractvalue(ptr dereferenceable(1024) align 8 %src, i32 noundef %x) {
; CHECK-LABEL: define i32 @early_exit_with_extractvalue(
More information about the llvm-commits
mailing list