[llvm] [InstCombine] Move nonnull assumptions to the base of a gep (PR #195650)

Nikolas Klauser via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 8 06:00:36 PDT 2026


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/195650

>From 959fcd7fff6c463a94b62bad4789ccde22dcb786 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Mon, 4 May 2026 15:18:09 +0200
Subject: [PATCH 1/2] [InstCombine] Move nonnull assumptions to the base of a
 gep

---
 .../InstCombine/InstCombineCalls.cpp          | 18 +++++++++++++
 llvm/test/Transforms/InstCombine/assume.ll    | 27 +++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 3bcec0827e9a1..1924d99c0f723 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3716,6 +3716,24 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
           return CallBase::removeOperandBundle(II, OBU.getTagID());
         }
 
+        // Move assume to the base pointer of a gep if it's inbounds
+        if (auto *GEP = dyn_cast<GEPOperator>(RK.WasOn); GEP && GEP->isInBounds()) {
+          while (true) {
+            auto *NextGEP = dyn_cast<GEPOperator>(GEP->getPointerOperand());
+            if (!NextGEP || !NextGEP->isInBounds())
+              break;
+            GEP = NextGEP;
+          }
+          if (auto *Replacement = buildAssumeFromKnowledge(
+                  {RetainedKnowledge{Attribute::NonNull, 0,
+                                     GEP->getPointerOperand()}},
+                  Next, &AC, &DT)) {
+            InsertNewInstBefore(Replacement, Next->getIterator());
+            AC.registerAssumption(Replacement);
+            return CallBase::removeOperandBundle(II, OBU.getTagID());
+          }
+        }
+
         // TODO: apply nonnull return attributes to calls and invokes
       }
     }
diff --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll
index 197d680babe11..b7976fef75e00 100644
--- a/llvm/test/Transforms/InstCombine/assume.ll
+++ b/llvm/test/Transforms/InstCombine/assume.ll
@@ -613,6 +613,33 @@ define void @nonnull_only_ephemeral_use(ptr %p) {
   ret void
 }
 
+define ptr @nonnull_gep(ptr %p, i64 %i) {
+; DEFAULT-LABEL: @nonnull_gep(
+; DEFAULT-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[I:%.*]]
+; DEFAULT-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P2]]) ]
+; DEFAULT-NEXT:    ret ptr [[P2]]
+;
+; BUNDLES-LABEL: @nonnull_gep(
+; BUNDLES-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[I:%.*]]
+; BUNDLES-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P]]) ]
+; BUNDLES-NEXT:    ret ptr [[P2]]
+;
+  %p2 = getelementptr i8, ptr %p, i64 %i
+  call void @llvm.assume(i1 true) ["nonnull"(ptr %p2)]
+  ret ptr %p2
+}
+
+define ptr @nonnull_gep_inbounds(ptr %p, i64 %i) {
+; CHECK-LABEL: @nonnull_gep_inbounds(
+; CHECK-NEXT:    [[P2:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[I:%.*]]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P]]) ]
+; CHECK-NEXT:    ret ptr [[P2]]
+;
+  %p2 = getelementptr inbounds i8, ptr %p, i64 %i
+  call void @llvm.assume(i1 true) ["nonnull"(ptr %p2)]
+  ret ptr %p2
+}
+
 define void @always_true_assumption() {
 ; CHECK-LABEL: @always_true_assumption(
 ; CHECK-NEXT:    ret void

>From 2d4af73141e92ddcd5c7bd08e826a79c5a5661ed Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 6 May 2026 19:46:34 +0200
Subject: [PATCH 2/2] Address comments

---
 .../InstCombine/InstCombineCalls.cpp          | 19 ++++---------------
 llvm/test/Transforms/InstCombine/assume.ll    |  5 ++---
 2 files changed, 6 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 6a8e3587dcfae..5fc4c937aaf46 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3706,21 +3706,10 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
         }
 
         // Move assume to the base pointer of a gep if it's inbounds
-        if (auto *GEP = dyn_cast<GEPOperator>(RK.WasOn); GEP && GEP->isInBounds()) {
-          while (true) {
-            auto *NextGEP = dyn_cast<GEPOperator>(GEP->getPointerOperand());
-            if (!NextGEP || !NextGEP->isInBounds())
-              break;
-            GEP = NextGEP;
-          }
-          if (auto *Replacement = buildAssumeFromKnowledge(
-                  {RetainedKnowledge{Attribute::NonNull, 0,
-                                     GEP->getPointerOperand()}},
-                  Next, &AC, &DT)) {
-            InsertNewInstBefore(Replacement, Next->getIterator());
-            AC.registerAssumption(Replacement);
-            return CallBase::removeOperandBundle(II, OBU.getTagID());
-          }
+        if (auto *GEP = dyn_cast<GEPOperator>(RK.WasOn);
+            GEP && GEP->isInBounds()) {
+          Builder.CreateNonnullAssumption(GEP->stripInBoundsOffsets());
+          return CallBase::removeOperandBundle(II, OBU.getTagID());
         }
 
         // TODO: apply nonnull return attributes to calls and invokes
diff --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll
index 5182c9844d851..35e7305df98d3 100644
--- a/llvm/test/Transforms/InstCombine/assume.ll
+++ b/llvm/test/Transforms/InstCombine/assume.ll
@@ -614,9 +614,8 @@ define void @nonnull_only_ephemeral_use(ptr %p) {
 
 define void @nonnull_gep_inbounds_bundle(ptr %p, i64 %i) {
 ; CHECK-LABEL: @nonnull_gep_inbounds_bundle(
-; CHECK-NEXT:    [[P2:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[I:%.*]]
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P]]) ]
-; CHECK-NEXT:    ret ptr [[P2]]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P:%.*]]) ]
+; CHECK-NEXT:    ret void
 ;
   %p2 = getelementptr inbounds i8, ptr %p, i64 %i
   call void @llvm.assume(i1 true) ["nonnull"(ptr %p2)]



More information about the llvm-commits mailing list