[llvm] [LVI] Handle nonnull attributes at callsite (PR #125377)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sat Feb 1 19:22:46 PST 2025
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/125377
This patch is the followup of https://github.com/llvm/llvm-project/pull/124908.
>From bcc27467398b0fbf16a4f944a48de12fc969c5b7 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sun, 2 Feb 2025 11:08:12 +0800
Subject: [PATCH 1/2] [CVP] Add pre-commit tests. NFC.
---
.../CorrelatedValuePropagation/non-null.ll | 71 +++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/non-null.ll b/llvm/test/Transforms/CorrelatedValuePropagation/non-null.ll
index 35d866ed2d92eb..10429ed90d6a22 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/non-null.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/non-null.ll
@@ -344,4 +344,75 @@ define i1 @test_store_same_block(ptr %arg) {
ret i1 %cmp
}
+
+define i1 @test_known_nonnull_at_callsite(ptr %src) {
+; CHECK-LABEL: @test_known_nonnull_at_callsite(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @callee(ptr noundef nonnull [[SRC:%.*]])
+; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
+; CHECK-NEXT: ret i1 [[NONNULL]]
+;
+entry:
+ call void @callee(ptr noundef nonnull %src)
+ %nonnull = icmp eq ptr %src, null
+ ret i1 %nonnull
+}
+
+define i1 @test_known_nonnull_mixed(ptr %src) {
+; CHECK-LABEL: @test_known_nonnull_mixed(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @callee2(ptr nonnull [[SRC:%.*]])
+; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
+; CHECK-NEXT: ret i1 [[NONNULL]]
+;
+entry:
+ call void @callee2(ptr nonnull %src)
+ %nonnull = icmp eq ptr %src, null
+ ret i1 %nonnull
+}
+
+define i1 @test_known_nonnull_at_callsite_dereferenceable(ptr %src) {
+; CHECK-LABEL: @test_known_nonnull_at_callsite_dereferenceable(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @callee(ptr dereferenceable(1) [[SRC:%.*]])
+; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
+; CHECK-NEXT: ret i1 [[NONNULL]]
+;
+entry:
+ call void @callee(ptr dereferenceable(1) %src)
+ %nonnull = icmp eq ptr %src, null
+ ret i1 %nonnull
+}
+
+; Negative tests
+
+define i1 @test_known_nonnull_at_callsite_without_noundef(ptr %src) {
+; CHECK-LABEL: @test_known_nonnull_at_callsite_without_noundef(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @callee(ptr nonnull [[SRC:%.*]])
+; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
+; CHECK-NEXT: ret i1 [[NONNULL]]
+;
+entry:
+ call void @callee(ptr nonnull %src)
+ %nonnull = icmp eq ptr %src, null
+ ret i1 %nonnull
+}
+
+define i1 @test_known_nonnull_at_callsite_dereferenceable_null_is_defined(ptr %src) #0 {
+; CHECK-LABEL: @test_known_nonnull_at_callsite_dereferenceable_null_is_defined(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @callee(ptr dereferenceable(1) [[SRC:%.*]])
+; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
+; CHECK-NEXT: ret i1 [[NONNULL]]
+;
+entry:
+ call void @callee(ptr dereferenceable(1) %src)
+ %nonnull = icmp eq ptr %src, null
+ ret i1 %nonnull
+}
+
+declare void @callee(ptr)
+declare void @callee2(ptr noundef)
+
attributes #0 = { null_pointer_is_valid }
>From c3bacf06324b96fb5d48c781b723a29c0e2cf4ca Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sun, 2 Feb 2025 11:21:10 +0800
Subject: [PATCH 2/2] [LVI] Handle nonnull at callsite
---
llvm/lib/Analysis/LazyValueInfo.cpp | 25 ++++++++++++++-----
.../CorrelatedValuePropagation/non-null.ll | 9 +++----
2 files changed, 22 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 20f69a0955f51c..14f07da4eefb15 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -780,12 +780,25 @@ void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange(
}
if (BBLV.isOverdefined()) {
- // Check whether we're checking at the terminator, and the pointer has
- // been dereferenced in this block.
- PointerType *PTy = dyn_cast<PointerType>(Val->getType());
- if (PTy && BB->getTerminator() == BBI &&
- isNonNullAtEndOfBlock(Val, BB))
- BBLV = ValueLatticeElement::getNot(ConstantPointerNull::get(PTy));
+ if (PointerType *PTy = dyn_cast<PointerType>(Val->getType())) {
+ // Check whether we're checking at the terminator, and the pointer has
+ // been dereferenced in this block.
+ if (BB->getTerminator() == BBI && isNonNullAtEndOfBlock(Val, BB))
+ BBLV = ValueLatticeElement::getNot(ConstantPointerNull::get(PTy));
+ else {
+ for (Use &U : Val->uses()) {
+ if (auto *CB = dyn_cast<CallBase>(U.getUser())) {
+ if (CB->isArgOperand(&U) &&
+ CB->paramHasNonNullAttr(CB->getArgOperandNo(&U),
+ /*AllowUndefOrPoison=*/false) &&
+ isValidAssumeForContext(CB, BBI)) {
+ BBLV = ValueLatticeElement::getNot(ConstantPointerNull::get(PTy));
+ break;
+ }
+ }
+ }
+ }
+ }
}
}
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/non-null.ll b/llvm/test/Transforms/CorrelatedValuePropagation/non-null.ll
index 10429ed90d6a22..090826e90ef568 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/non-null.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/non-null.ll
@@ -349,8 +349,7 @@ define i1 @test_known_nonnull_at_callsite(ptr %src) {
; CHECK-LABEL: @test_known_nonnull_at_callsite(
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @callee(ptr noundef nonnull [[SRC:%.*]])
-; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
-; CHECK-NEXT: ret i1 [[NONNULL]]
+; CHECK-NEXT: ret i1 false
;
entry:
call void @callee(ptr noundef nonnull %src)
@@ -362,8 +361,7 @@ define i1 @test_known_nonnull_mixed(ptr %src) {
; CHECK-LABEL: @test_known_nonnull_mixed(
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @callee2(ptr nonnull [[SRC:%.*]])
-; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
-; CHECK-NEXT: ret i1 [[NONNULL]]
+; CHECK-NEXT: ret i1 false
;
entry:
call void @callee2(ptr nonnull %src)
@@ -375,8 +373,7 @@ define i1 @test_known_nonnull_at_callsite_dereferenceable(ptr %src) {
; CHECK-LABEL: @test_known_nonnull_at_callsite_dereferenceable(
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @callee(ptr dereferenceable(1) [[SRC:%.*]])
-; CHECK-NEXT: [[NONNULL:%.*]] = icmp eq ptr [[SRC]], null
-; CHECK-NEXT: ret i1 [[NONNULL]]
+; CHECK-NEXT: ret i1 false
;
entry:
call void @callee(ptr dereferenceable(1) %src)
More information about the llvm-commits
mailing list