[llvm] [InstCombine] Drop nonnull assumes if the pointer is already known to be nonnull (PR #180434)
Nikolas Klauser via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 9 03:25:55 PST 2026
https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/180434
>From 547222c44ef5746d8693f79c347690ab64ac3730 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sun, 8 Feb 2026 20:30:05 +0100
Subject: [PATCH] [InstCombine] Drop nonnull assumes if the pointer is already
known to be nonnull
---
.../InstCombine/InstCombineCalls.cpp | 10 +++++
.../ValueTracking/assume-queries-counter.ll | 11 +++---
llvm/test/Transforms/InstCombine/assume.ll | 37 +++++++++++++++++++
.../d83507-knowledge-retention-bug.ll | 1 -
4 files changed, 53 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 7be083c2ebbd7..90bbd102868c5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3671,6 +3671,16 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
continue;
return CallBase::removeOperandBundle(II, OBU.getTagID());
}
+
+ if (OBU.getTagName() == "nonnull" && OBU.Inputs.size() == 1) {
+ RetainedKnowledge RK = getKnowledgeFromOperandInAssume(
+ *cast<AssumeInst>(II), II->arg_size() + Idx);
+ if (!RK || RK.AttrKind != Attribute::NonNull ||
+ !isKnownNonZero(RK.WasOn,
+ getSimplifyQuery().getWithInstruction(II)))
+ continue;
+ return CallBase::removeOperandBundle(II, OBU.getTagID());
+ }
}
// Convert nonnull assume like:
diff --git a/llvm/test/Analysis/ValueTracking/assume-queries-counter.ll b/llvm/test/Analysis/ValueTracking/assume-queries-counter.ll
index 754e43d327f50..0cb8279f3db38 100644
--- a/llvm/test/Analysis/ValueTracking/assume-queries-counter.ll
+++ b/llvm/test/Analysis/ValueTracking/assume-queries-counter.ll
@@ -1,8 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -passes=instcombine --debug-counter=assume-queries-counter=0 -S | FileCheck %s --check-prefixes=COUNTER1
-; RUN: opt < %s -passes=instcombine --debug-counter=assume-queries-counter=1-2 -S | FileCheck %s --check-prefixes=COUNTER2
-; RUN: opt < %s -passes=instcombine --debug-counter=assume-queries-counter=2-6 -S | FileCheck %s --check-prefixes=COUNTER3
+; RUN: opt < %s -passes=instcombine --debug-counter=assume-queries-counter=1 -S | FileCheck %s --check-prefixes=COUNTER1
+; RUN: opt < %s -passes=instcombine --debug-counter=assume-queries-counter=2-3 -S | FileCheck %s --check-prefixes=COUNTER2
+; RUN: opt < %s -passes=instcombine --debug-counter=assume-queries-counter=4-7 -S | FileCheck %s --check-prefixes=COUNTER3
declare i1 @get_val()
declare void @llvm.assume(i1)
@@ -38,8 +38,9 @@ define dso_local i1 @test2(ptr readonly %0) {
; COUNTER2-NEXT: ret i1 false
;
; COUNTER3-LABEL: @test2(
-; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[TMP0:%.*]]) ]
-; COUNTER3-NEXT: ret i1 false
+; COUNTER3-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0:%.*]], null
+; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[TMP0]]) ]
+; COUNTER3-NEXT: ret i1 [[TMP2]]
;
%2 = icmp eq ptr %0, null
call void @llvm.assume(i1 true) ["nonnull"(ptr %0)]
diff --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll
index a4c7963df1783..c3a193b9fc6c4 100644
--- a/llvm/test/Transforms/InstCombine/assume.ll
+++ b/llvm/test/Transforms/InstCombine/assume.ll
@@ -419,6 +419,43 @@ define i1 @nonnull5(ptr %a) {
ret i1 %rval
}
+define void @redundant_nonnull1(ptr nonnull %ptr) {
+; CHECK-LABEL: @redundant_nonnull1(
+; CHECK-NEXT: ret void
+;
+ call void @llvm.assume(i1 true) [ "nonnull"(ptr %ptr) ]
+ ret void
+}
+
+define void @redundant_nonnull2(ptr %ptr) {
+; CHECK-LABEL: @redundant_nonnull2(
+; CHECK-NEXT: [[NULL_CMP_NOT:%.*]] = icmp eq ptr [[PTR:%.*]], null
+; CHECK-NEXT: br i1 [[NULL_CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
+; CHECK: true:
+; CHECK-NEXT: ret void
+; CHECK: false:
+; CHECK-NEXT: ret void
+;
+ %cmp = icmp ne ptr %ptr, null
+ br i1 %cmp, label %true, label %false
+true:
+ call void @llvm.assume(i1 true) [ "nonnull"(ptr %ptr) ]
+ ret void
+
+false:
+ ret void
+}
+
+define void @redundant_nonnull3(ptr %ptr) {
+; CHECK-LABEL: @redundant_nonnull3(
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[PTR:%.*]]) ]
+; CHECK-NEXT: ret void
+;
+ call void @llvm.assume(i1 true) [ "nonnull"(ptr %ptr) ]
+ call void @llvm.assume(i1 true) [ "nonnull"(ptr %ptr) ]
+ ret void
+}
+
; PR35846 - https://bugs.llvm.org/show_bug.cgi?id=35846
define i32 @assumption_conflicts_with_known_bits(i32 %a, i32 %b) {
diff --git a/llvm/test/Transforms/PhaseOrdering/d83507-knowledge-retention-bug.ll b/llvm/test/Transforms/PhaseOrdering/d83507-knowledge-retention-bug.ll
index e903004461728..61380d5a78c90 100644
--- a/llvm/test/Transforms/PhaseOrdering/d83507-knowledge-retention-bug.ll
+++ b/llvm/test/Transforms/PhaseOrdering/d83507-knowledge-retention-bug.ll
@@ -13,7 +13,6 @@ define ptr @f1(ptr %i0) {
; CHECK-NEXT: br label %[[LOOP_LATCH:.*]]
; CHECK: [[LOOP_LATCH]]:
; CHECK-NEXT: [[I3:%.*]] = phi ptr [ [[I0]], %[[LOOP_LATCH_LR_PH]] ], [ [[I5:%.*]], %[[LOOP_LATCH]] ]
-; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[I3]]) ]
; CHECK-NEXT: [[I5]] = load ptr, ptr [[I3]], align 8
; CHECK-NEXT: [[I2:%.*]] = icmp eq ptr [[I5]], null
; CHECK-NEXT: br i1 [[I2]], label %[[LOOP_EXIT_CRIT_EDGE:.*]], label %[[LOOP_LATCH]]
More information about the llvm-commits
mailing list