[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