From 56e2be992b21264f561e530bef10c1c53efc7c91 Mon Sep 17 00:00:00 2001 From: Andreas Jonson 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 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(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(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 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(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