[llvm] [ValueTracking] Infer nonzero from assumed masked value (PR #224709)

Tejas Gaikwad via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 28 11:50:39 PDT 2026


https://github.com/tejasgaikwad04 updated https://github.com/llvm/llvm-project/pull/224709

>From 8273ee61321939fb091c695dfb331dd43207b653 Mon Sep 17 00:00:00 2001
From: Tejas Gaikwad <tgaikwad966 at gmail.com>
Date: Fri, 18 Sep 2026 18:56:50 +0000
Subject: [PATCH] [ValueTracking] Infer nonzero from assumed masked value

---
 llvm/lib/Analysis/ValueTracking.cpp           |  7 ++--
 .../Analysis/ValueTracking/known-non-zero.ll  | 38 +++++++++++++++++++
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index e028768f3a487..a3767bf271ba3 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -879,11 +879,12 @@ static bool isKnownNonZeroFromAssume(const Value *V, const SimplifyQuery &Q) {
     Value *RHS;
     CmpPredicate Pred;
     auto m_V = m_CombineOr(m_Specific(V), m_PtrToInt(m_Specific(V)));
-    if (!match(I->getArgOperand(0), m_c_ICmp(Pred, m_V, m_Value(RHS))))
-      continue;
+    auto m_VOrAnd = m_CombineOr(m_V, m_c_And(m_V, m_Value()));
 
-    if (cmpExcludesZero(Pred, RHS) && isValidAssumeForContext(I, Q))
+    if (match(I->getArgOperand(0), m_c_ICmp(Pred, m_VOrAnd, m_Value(RHS))) &&
+        cmpExcludesZero(Pred, RHS) && isValidAssumeForContext(I, Q))
       return true;
+    // Check whether the assumption proves V is non-zero through an AND.
   }
 
   return false;
diff --git a/llvm/test/Analysis/ValueTracking/known-non-zero.ll b/llvm/test/Analysis/ValueTracking/known-non-zero.ll
index f02ff583e5cbb..6f6d4854802d7 100644
--- a/llvm/test/Analysis/ValueTracking/known-non-zero.ll
+++ b/llvm/test/Analysis/ValueTracking/known-non-zero.ll
@@ -1547,3 +1547,41 @@ define i1 @vec_reverse_non_zero_demanded_fail(<4 x i8> %xx) {
 }
 
 declare i32 @llvm.experimental.get.vector.length.i32(i32, i32, i1)
+
+define i1 @assume_masked_nonzero(i8 %x) {
+; CHECK-LABEL: @assume_masked_nonzero(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TWICE_MASK:%.*]] = and i8 [[X:%.*]], 127
+; CHECK-NEXT:    [[TWICE_NZ:%.*]] = icmp ne i8 [[TWICE_MASK]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[TWICE_NZ]])
+; CHECK-NEXT:    [[DEC:%.*]] = add i8 [[X]], -1
+; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[DEC]], 7
+; CHECK-NEXT:    ret i1 [[R]]
+;
+entry:
+  %twice.mask = and i8 %x, 127
+  %twice.nz = icmp ne i8 %twice.mask, 0
+  call void @llvm.assume(i1 %twice.nz)
+  %dec = add i8 %x, -1
+  %r = icmp ult i8 %dec, 7
+  ret i1 %r
+}
+
+define i1 @assume_masked_nonzero_commuted(i8 %x) {
+; CHECK-LABEL: @assume_masked_nonzero_commuted(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TWICE_MASK:%.*]] = and i8 127, [[X:%.*]]
+; CHECK-NEXT:    [[TWICE_NZ:%.*]] = icmp ne i8 [[TWICE_MASK]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[TWICE_NZ]])
+; CHECK-NEXT:    [[DEC:%.*]] = add i8 [[X]], -1
+; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[DEC]], 7
+; CHECK-NEXT:    ret i1 [[R]]
+;
+entry:
+  %twice.mask = and i8 127, %x
+  %twice.nz = icmp ne i8 %twice.mask, 0
+  call void @llvm.assume(i1 %twice.nz)
+  %dec = add i8 %x, -1
+  %r = icmp ult i8 %dec, 7
+  ret i1 %r
+}



More information about the llvm-commits mailing list