[llvm] [InstCombine] Drop zero size dereferenceable assumptions (PR #202411)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 8 11:54:15 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-ir

Author: Nikolas Klauser (philnik777)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/202411.diff


7 Files Affected:

- (modified) llvm/include/llvm/IR/BundleAttributes.h (+1) 
- (modified) llvm/lib/Analysis/LazyValueInfo.cpp (+4-5) 
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+4-8) 
- (modified) llvm/lib/IR/BundleAttributes.cpp (+5-1) 
- (modified) llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp (+8-1) 
- (modified) llvm/test/Analysis/ValueTracking/assume.ll (+1-2) 
- (modified) llvm/test/Transforms/InstCombine/assume.ll (+35) 


``````````diff
diff --git a/llvm/include/llvm/IR/BundleAttributes.h b/llvm/include/llvm/IR/BundleAttributes.h
index ee6e5b4bc1ef6..9b1b42607a515 100644
--- a/llvm/include/llvm/IR/BundleAttributes.h
+++ b/llvm/include/llvm/IR/BundleAttributes.h
@@ -39,6 +39,7 @@ LLVM_ABI AssumeAlignInfo getAssumeAlignInfo(OperandBundleUse);
 struct AssumeDereferenceableInfo {
   const Use &Ptr;
   const Use &Count;
+  std::optional<uint64_t> CountVal;
 };
 
 LLVM_ABI
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 7a56a278c5e1e..b052352b51eec 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -866,12 +866,11 @@ void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange(
         break;
 
       case BundleAttr::Dereferenceable: {
-        auto [Ptr, Count] = getAssumeDereferenceableInfo(OBU);
-        if (Ptr != Val)
+        auto [Ptr, _, Count] = getAssumeDereferenceableInfo(OBU);
+        if (Ptr != Val || !Count || *Count == 0)
           break;
-        if (auto *CI = dyn_cast<ConstantInt>(Count); CI && !CI->isZero())
-          BBLV = BBLV.intersect(ValueLatticeElement::getNot(
-              Constant::getNullValue(Val->getType())));
+        BBLV = BBLV.intersect(ValueLatticeElement::getNot(
+            Constant::getNullValue(Val->getType())));
       } break;
 
       default:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index e648ef5494130..fa492585035b5 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -832,14 +832,10 @@ static bool isKnownNonZeroFromAssume(const Value *V, const SimplifyQuery &Q) {
         auto OBU = I->getOperandBundleAt(Elem.Index);
         switch (getBundleAttrFromOBU(OBU)) {
         case BundleAttr::Dereferenceable: {
-          auto [Ptr, Count] = getAssumeDereferenceableInfo(OBU);
-          if (Ptr != V ||
-              NullPointerIsDefined(Q.CxtI->getFunction(),
-                                   V->getType()->getPointerAddressSpace()))
-            return false;
-
-          auto *CI = dyn_cast<ConstantInt>(Count);
-          return CI && !CI->isZero();
+          auto [Ptr, _, Count] = getAssumeDereferenceableInfo(OBU);
+          return Ptr == V && Count && *Count != 0 &&
+                 !NullPointerIsDefined(Q.CxtI->getFunction(),
+                                       V->getType()->getPointerAddressSpace());
         }
 
         case BundleAttr::NonNull:
diff --git a/llvm/lib/IR/BundleAttributes.cpp b/llvm/lib/IR/BundleAttributes.cpp
index 3e4e65e8fd3d1..a6aee2acc6811 100644
--- a/llvm/lib/IR/BundleAttributes.cpp
+++ b/llvm/lib/IR/BundleAttributes.cpp
@@ -60,5 +60,9 @@ AssumeNonNullInfo llvm::getAssumeNonNullInfo(OperandBundleUse OBU) {
 AssumeDereferenceableInfo
 llvm::getAssumeDereferenceableInfo(OperandBundleUse OBU) {
   assert(OBU.getTagName() == "dereferenceable" && OBU.Inputs.size() == 2);
-  return {OBU.Inputs[0], OBU.Inputs[1]};
+  AssumeDereferenceableInfo Ret{OBU.Inputs[0], OBU.Inputs[1], std::nullopt};
+
+  if (auto *Size = dyn_cast<ConstantInt>(OBU.Inputs[1]))
+    Ret.CountVal = Size->getZExtValue();
+  return Ret;
 }
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index c7c153df27f62..0c7e1893ccab0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3678,6 +3678,14 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
         return CallBase::removeOperandBundleAt(II, Idx);
       }
 
+      case BundleAttr::Dereferenceable: {
+        auto [Ptr, _, Count] = getAssumeDereferenceableInfo(OBU);
+
+        if (Count && *Count == 0)
+          return CallBase::removeOperandBundleAt(II, Idx);
+        break;
+      }
+
       case BundleAttr::NonNull: {
         auto [Ptr] = llvm::getAssumeNonNullInfo(OBU);
 
@@ -3718,7 +3726,6 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
       } break;
 
       // TODO: Drop these assumes when they are redundant
-      case BundleAttr::Dereferenceable:
       case BundleAttr::DereferenceableOrNull:
       case BundleAttr::Ignore:
       case BundleAttr::NoUndef:
diff --git a/llvm/test/Analysis/ValueTracking/assume.ll b/llvm/test/Analysis/ValueTracking/assume.ll
index c5fe253634716..09efbdac20cf4 100644
--- a/llvm/test/Analysis/ValueTracking/assume.ll
+++ b/llvm/test/Analysis/ValueTracking/assume.ll
@@ -173,8 +173,7 @@ define i1 @test_dereferenceable_unknown_size_not_nonnull(ptr %ptr, i32 %bytes) {
 
 define i1 @test_dereferenceable_zero_size_not_nonnull(ptr %ptr) {
 ; CHECK-LABEL: @test_dereferenceable_zero_size_not_nonnull(
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP0:%.*]], i32 0) ]
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[TMP0:%.*]], null
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
   call void @llvm.assume(i1 true) ["dereferenceable"(ptr %ptr, i32 0)]
diff --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll
index c1ccb49209227..5b576d8b9dc8b 100644
--- a/llvm/test/Transforms/InstCombine/assume.ll
+++ b/llvm/test/Transforms/InstCombine/assume.ll
@@ -1211,6 +1211,41 @@ define i1 @neg_assume_trunc_eq_one(i8 %x) {
   ret i1 %q
 }
 
+define void @assume_dereferenceable_0(ptr %ptr) {
+; CHECK-LABEL: @assume_dereferenceable_0(
+; CHECK-NEXT:    ret void
+;
+  call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %ptr, i64 0) ]
+  ret void
+}
+
+define void @assume_dereferenceable_1(ptr %ptr) {
+; CHECK-LABEL: @assume_dereferenceable_1(
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR:%.*]], i64 1) ]
+; CHECK-NEXT:    ret void
+;
+  call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %ptr, i64 1) ]
+  ret void
+}
+
+define void @assume_dereferenceable_variable(ptr %ptr, i64 %count) {
+; CHECK-LABEL: @assume_dereferenceable_variable(
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR:%.*]], i64 [[COUNT:%.*]]) ]
+; CHECK-NEXT:    ret void
+;
+  call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %ptr, i64 %count) ]
+  ret void
+}
+
+define void @assume_dereferenceable_variable_on_nullptr(i64 %count) {
+; CHECK-LABEL: @assume_dereferenceable_variable_on_nullptr(
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(ptr null, i64 [[COUNT:%.*]]) ]
+; CHECK-NEXT:    ret void
+;
+  call void @llvm.assume(i1 true) [ "dereferenceable"(ptr null, i64 %count) ]
+  ret void
+}
+
 declare void @use(i1)
 declare void @llvm.dbg.value(metadata, metadata, metadata)
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/202411


More information about the llvm-commits mailing list