[llvm] [PredicateInfo] Handle trunc nuw i1 condition. (PR #152988)

Andreas Jonson via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 11 03:11:52 PDT 2025


https://github.com/andjo403 created https://github.com/llvm/llvm-project/pull/152988

proof: https://alive2.llvm.org/ce/z/mxtn4L

part of changes needed for move of https://github.com/llvm/llvm-project/pull/151961 to SCCP

>From 56e2be992b21264f561e530bef10c1c53efc7c91 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Mon, 11 Aug 2025 11:48:39 +0200
Subject: [PATCH 1/2] [PredicateInfo] Add test for trunc nuw condition (NFC)

---
 llvm/test/Transforms/SCCP/assume.ll           | 54 +++++++++++++++
 .../test/Transforms/SCCP/conditions-ranges.ll | 66 +++++++++++++++++++
 2 files changed, 120 insertions(+)

diff --git a/llvm/test/Transforms/SCCP/assume.ll b/llvm/test/Transforms/SCCP/assume.ll
index 8146d58d9a897..df7347442bff6 100644
--- a/llvm/test/Transforms/SCCP/assume.ll
+++ b/llvm/test/Transforms/SCCP/assume.ll
@@ -69,3 +69,57 @@ define void @nonnull(ptr %v) {
   call void @use(i1 %c4)
   ret void
 }
+
+define void @trunc_nuw(i8 %v) {
+; CHECK-LABEL: @trunc_nuw(
+; CHECK-NEXT:    [[A:%.*]] = trunc nuw i8 [[V:%.*]] to i1
+; CHECK-NEXT:    call void @llvm.assume(i1 [[A]])
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[V]], 0
+; CHECK-NEXT:    call void @use(i1 [[C1]])
+; CHECK-NEXT:    [[C2:%.*]] = icmp ne i8 [[V]], 0
+; CHECK-NEXT:    call void @use(i1 [[C2]])
+; CHECK-NEXT:    [[C3:%.*]] = icmp eq i8 0, [[V]]
+; CHECK-NEXT:    call void @use(i1 [[C3]])
+; CHECK-NEXT:    [[C4:%.*]] = icmp ne i8 0, [[V]]
+; CHECK-NEXT:    call void @use(i1 [[C4]])
+; CHECK-NEXT:    ret void
+;
+  %a = trunc nuw i8 %v to i1
+  call void @llvm.assume(i1 %a)
+  %c1 = icmp eq i8 %v, 0
+  call void @use(i1 %c1)
+  %c2 = icmp ne i8 %v, 0
+  call void @use(i1 %c2)
+  %c3 = icmp eq i8 0, %v
+  call void @use(i1 %c3)
+  %c4 = icmp ne i8 0, %v
+  call void @use(i1 %c4)
+  ret void
+}
+
+define void @neg_trunc(i8 %v) {
+; CHECK-LABEL: @neg_trunc(
+; CHECK-NEXT:    [[A:%.*]] = trunc i8 [[V:%.*]] to i1
+; CHECK-NEXT:    call void @llvm.assume(i1 [[A]])
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[V]], 0
+; CHECK-NEXT:    call void @use(i1 [[C1]])
+; CHECK-NEXT:    [[C2:%.*]] = icmp ne i8 [[V]], 0
+; CHECK-NEXT:    call void @use(i1 [[C2]])
+; CHECK-NEXT:    [[C3:%.*]] = icmp eq i8 0, [[V]]
+; CHECK-NEXT:    call void @use(i1 [[C3]])
+; CHECK-NEXT:    [[C4:%.*]] = icmp ne i8 0, [[V]]
+; CHECK-NEXT:    call void @use(i1 [[C4]])
+; CHECK-NEXT:    ret void
+;
+  %a = trunc i8 %v to i1
+  call void @llvm.assume(i1 %a)
+  %c1 = icmp eq i8 %v, 0
+  call void @use(i1 %c1)
+  %c2 = icmp ne i8 %v, 0
+  call void @use(i1 %c2)
+  %c3 = icmp eq i8 0, %v
+  call void @use(i1 %c3)
+  %c4 = icmp ne i8 0, %v
+  call void @use(i1 %c4)
+  ret void
+}
diff --git a/llvm/test/Transforms/SCCP/conditions-ranges.ll b/llvm/test/Transforms/SCCP/conditions-ranges.ll
index bb3764160f724..c69637e046a46 100644
--- a/llvm/test/Transforms/SCCP/conditions-ranges.ll
+++ b/llvm/test/Transforms/SCCP/conditions-ranges.ll
@@ -1444,3 +1444,69 @@ define i1 @ptr_icmp_data_layout() {
   %cmp = icmp eq ptr %a.end, @A
   ret i1 %cmp
 }
+
+define void @trunc_nuw_1_dominating_icmp_ne_0(i8 %x) {
+; CHECK-LABEL: @trunc_nuw_1_dominating_icmp_ne_0(
+; CHECK-NEXT:    [[TRUNC:%.*]] = trunc nuw i8 [[X:%.*]] to i1
+; CHECK-NEXT:    br i1 [[TRUNC]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X]], 0
+; CHECK-NEXT:    call void @use(i1 [[C1]])
+; CHECK-NEXT:    [[C2:%.*]] = icmp ne i8 0, [[X]]
+; CHECK-NEXT:    call void @use(i1 [[C2]])
+; CHECK-NEXT:    ret void
+; CHECK:       bb2:
+; CHECK-NEXT:    [[C3:%.*]] = icmp ne i8 [[X]], 0
+; CHECK-NEXT:    call void @use(i1 [[C3]])
+; CHECK-NEXT:    [[C4:%.*]] = icmp ne i8 0, [[X]]
+; CHECK-NEXT:    call void @use(i1 [[C4]])
+; CHECK-NEXT:    ret void
+;
+  %trunc = trunc nuw i8 %x to i1
+  br i1 %trunc, label %bb1, label %bb2
+bb1:
+  %c1 = icmp ne i8 %x , 0
+  call void @use(i1 %c1)
+  %c2 = icmp ne i8 0, %x
+  call void @use(i1 %c2)
+  ret void
+bb2:
+  %c3 = icmp ne i8 %x , 0
+  call void @use(i1 %c3)
+  %c4 = icmp ne i8 0, %x
+  call void @use(i1 %c4)
+  ret void
+}
+
+define void @neg_trunc_1_dominating_icmp_ne_0(i8 %x) {
+; CHECK-LABEL: @neg_trunc_1_dominating_icmp_ne_0(
+; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i8 [[X:%.*]] to i1
+; CHECK-NEXT:    br i1 [[TRUNC]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X]], 0
+; CHECK-NEXT:    call void @use(i1 [[C1]])
+; CHECK-NEXT:    [[C2:%.*]] = icmp ne i8 0, [[X]]
+; CHECK-NEXT:    call void @use(i1 [[C2]])
+; CHECK-NEXT:    ret void
+; CHECK:       bb2:
+; CHECK-NEXT:    [[C3:%.*]] = icmp ne i8 [[X]], 0
+; CHECK-NEXT:    call void @use(i1 [[C3]])
+; CHECK-NEXT:    [[C4:%.*]] = icmp ne i8 0, [[X]]
+; CHECK-NEXT:    call void @use(i1 [[C4]])
+; CHECK-NEXT:    ret void
+;
+  %trunc = trunc i8 %x to i1
+  br i1 %trunc, label %bb1, label %bb2
+bb1:
+  %c1 = icmp ne i8 %x , 0
+  call void @use(i1 %c1)
+  %c2 = icmp ne i8 0, %x
+  call void @use(i1 %c2)
+  ret void
+bb2:
+  %c3 = icmp ne i8 %x , 0
+  call void @use(i1 %c3)
+  %c4 = icmp ne i8 0, %x
+  call void @use(i1 %c4)
+  ret void
+}

>From 86b1bfc771d8250e3671f0c9783a4a97b6302fc4 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Mon, 11 Aug 2025 11:57:17 +0200
Subject: [PATCH 2/2] [PredicateInfo] Handle trunc nuw i1 condition.

---
 llvm/lib/Transforms/Utils/PredicateInfo.cpp    |  9 +++++++++
 llvm/test/Transforms/SCCP/assume.ll            | 12 ++++--------
 llvm/test/Transforms/SCCP/conditions-ranges.ll | 12 ++++--------
 3 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/PredicateInfo.cpp b/llvm/lib/Transforms/Utils/PredicateInfo.cpp
index 02420fa8abd97..38a312a3715c9 100644
--- a/llvm/lib/Transforms/Utils/PredicateInfo.cpp
+++ b/llvm/lib/Transforms/Utils/PredicateInfo.cpp
@@ -370,6 +370,8 @@ void PredicateInfoBuilder::processAssume(
     Values.push_back(Cond);
     if (auto *Cmp = dyn_cast<CmpInst>(Cond))
       collectCmpOps(Cmp, Values);
+    else if (match(Cond, m_NUWTrunc(m_Value(Op0))))
+      Values.push_back(Op0);
 
     for (Value *V : Values) {
       if (shouldRename(V)) {
@@ -416,6 +418,8 @@ void PredicateInfoBuilder::processBranch(
       Values.push_back(Cond);
       if (auto *Cmp = dyn_cast<CmpInst>(Cond))
         collectCmpOps(Cmp, Values);
+      else if (match(Cond, m_NUWTrunc(m_Value(Op0))))
+        Values.push_back(Op0);
 
       for (Value *V : Values) {
         if (shouldRename(V)) {
@@ -709,6 +713,11 @@ std::optional<PredicateConstraint> PredicateBase::getConstraint() const {
                         : ConstantInt::getFalse(Condition->getType())}};
     }
 
+    if (match(Condition, m_NUWTrunc(m_Specific(RenamedOp)))) {
+      return {{TrueEdge ? CmpInst::ICMP_NE : CmpInst::ICMP_EQ,
+               ConstantInt::getNullValue(RenamedOp->getType())}};
+    }
+
     CmpInst *Cmp = dyn_cast<CmpInst>(Condition);
     if (!Cmp) {
       // TODO: Make this an assertion once RenamedOp is fully accurate.
diff --git a/llvm/test/Transforms/SCCP/assume.ll b/llvm/test/Transforms/SCCP/assume.ll
index df7347442bff6..9beee934bb509 100644
--- a/llvm/test/Transforms/SCCP/assume.ll
+++ b/llvm/test/Transforms/SCCP/assume.ll
@@ -74,14 +74,10 @@ define void @trunc_nuw(i8 %v) {
 ; CHECK-LABEL: @trunc_nuw(
 ; CHECK-NEXT:    [[A:%.*]] = trunc nuw i8 [[V:%.*]] to i1
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A]])
-; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[V]], 0
-; CHECK-NEXT:    call void @use(i1 [[C1]])
-; CHECK-NEXT:    [[C2:%.*]] = icmp ne i8 [[V]], 0
-; CHECK-NEXT:    call void @use(i1 [[C2]])
-; CHECK-NEXT:    [[C3:%.*]] = icmp eq i8 0, [[V]]
-; CHECK-NEXT:    call void @use(i1 [[C3]])
-; CHECK-NEXT:    [[C4:%.*]] = icmp ne i8 0, [[V]]
-; CHECK-NEXT:    call void @use(i1 [[C4]])
+; CHECK-NEXT:    call void @use(i1 false)
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    call void @use(i1 false)
+; CHECK-NEXT:    call void @use(i1 true)
 ; CHECK-NEXT:    ret void
 ;
   %a = trunc nuw i8 %v to i1
diff --git a/llvm/test/Transforms/SCCP/conditions-ranges.ll b/llvm/test/Transforms/SCCP/conditions-ranges.ll
index c69637e046a46..7a64778b60789 100644
--- a/llvm/test/Transforms/SCCP/conditions-ranges.ll
+++ b/llvm/test/Transforms/SCCP/conditions-ranges.ll
@@ -1450,16 +1450,12 @@ define void @trunc_nuw_1_dominating_icmp_ne_0(i8 %x) {
 ; CHECK-NEXT:    [[TRUNC:%.*]] = trunc nuw i8 [[X:%.*]] to i1
 ; CHECK-NEXT:    br i1 [[TRUNC]], label [[BB1:%.*]], label [[BB2:%.*]]
 ; CHECK:       bb1:
-; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X]], 0
-; CHECK-NEXT:    call void @use(i1 [[C1]])
-; CHECK-NEXT:    [[C2:%.*]] = icmp ne i8 0, [[X]]
-; CHECK-NEXT:    call void @use(i1 [[C2]])
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    call void @use(i1 true)
 ; CHECK-NEXT:    ret void
 ; CHECK:       bb2:
-; CHECK-NEXT:    [[C3:%.*]] = icmp ne i8 [[X]], 0
-; CHECK-NEXT:    call void @use(i1 [[C3]])
-; CHECK-NEXT:    [[C4:%.*]] = icmp ne i8 0, [[X]]
-; CHECK-NEXT:    call void @use(i1 [[C4]])
+; CHECK-NEXT:    call void @use(i1 false)
+; CHECK-NEXT:    call void @use(i1 false)
 ; CHECK-NEXT:    ret void
 ;
   %trunc = trunc nuw i8 %x to i1



More information about the llvm-commits mailing list