[llvm] [SimplifyCfg] Handle trunc nuw i1 condition in Equality comparison. (PR #153051)
Andreas Jonson via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 11 10:11:57 PDT 2025
https://github.com/andjo403 created https://github.com/llvm/llvm-project/pull/153051
proof: https://alive2.llvm.org/ce/z/WVt4-F
>From e12a2c0d761e9d58992007ce47a06d6e45860f18 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Mon, 11 Aug 2025 19:07:15 +0200
Subject: [PATCH 1/2] [SimplifyCfg] Add test for trunc nuw i1 condition in
Equality comparison. (NFC)
---
.../Transforms/SimplifyCFG/switch_create.ll | 57 +++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/llvm/test/Transforms/SimplifyCFG/switch_create.ll b/llvm/test/Transforms/SimplifyCFG/switch_create.ll
index f446d718f8206..fe08e6be35aed 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch_create.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch_create.ll
@@ -1068,3 +1068,60 @@ if:
else:
ret void
}
+
+define void @trunc_nuw_i1_condition(i32 %V) {
+; CHECK-LABEL: @trunc_nuw_i1_condition(
+; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[V:%.*]], 2
+; CHECK-NEXT: [[C2:%.*]] = trunc nuw i32 [[V]] to i1
+; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
+; CHECK-NEXT: br i1 [[OR_COND]], label [[F:%.*]], label [[T:%.*]]
+; CHECK: common.ret:
+; CHECK-NEXT: ret void
+; CHECK: T:
+; CHECK-NEXT: call void @foo1()
+; CHECK-NEXT: br label [[COMMON_RET:%.*]]
+; CHECK: F:
+; CHECK-NEXT: call void @foo2()
+; CHECK-NEXT: br label [[COMMON_RET]]
+;
+ %C1 = icmp eq i32 %V, 2
+ br i1 %C1, label %T, label %N
+N:
+ %C2 = trunc nuw i32 %V to i1
+ br i1 %C2, label %F, label %T
+T:
+ call void @foo1( )
+ ret void
+F:
+ call void @foo2( )
+ ret void
+}
+
+define void @neg_trunc_i1_condition(i32 %V) {
+; CHECK-LABEL: @neg_trunc_i1_condition(
+; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[V:%.*]], 2
+; CHECK-NEXT: [[C2:%.*]] = trunc i32 [[V]] to i1
+; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[C1]], [[C2]]
+; CHECK-NEXT: br i1 [[OR_COND]], label [[F:%.*]], label [[T:%.*]]
+; CHECK: common.ret:
+; CHECK-NEXT: ret void
+; CHECK: T:
+; CHECK-NEXT: call void @foo1()
+; CHECK-NEXT: br label [[COMMON_RET:%.*]]
+; CHECK: F:
+; CHECK-NEXT: call void @foo2()
+; CHECK-NEXT: br label [[COMMON_RET]]
+;
+ %C1 = icmp eq i32 %V, 2
+ br i1 %C1, label %T, label %N
+N:
+ %C2 = trunc i32 %V to i1
+ br i1 %C2, label %F, label %T
+T:
+ call void @foo1( )
+ ret void
+F:
+ call void @foo2( )
+ ret void
+}
+
>From 4823fc6ca48bf1783a95cd526519e0e6f3103114 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Mon, 11 Aug 2025 19:07:37 +0200
Subject: [PATCH 2/2] [SimplifyCfg] Handle trunc nuw i1 condition in Equality
comparison.
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 30 ++++++++++++++-----
.../Transforms/SimplifyCFG/switch_create.ll | 8 ++---
2 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index deabacc592c7f..b409af483ad1e 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -810,11 +810,15 @@ Value *SimplifyCFGOpt::isValueEqualityComparison(Instruction *TI) {
if (!SI->getParent()->hasNPredecessorsOrMore(128 / SI->getNumSuccessors()))
CV = SI->getCondition();
} else if (BranchInst *BI = dyn_cast<BranchInst>(TI))
- if (BI->isConditional() && BI->getCondition()->hasOneUse())
+ if (BI->isConditional() && BI->getCondition()->hasOneUse()) {
if (ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition())) {
if (ICI->isEquality() && getConstantInt(ICI->getOperand(1), DL))
CV = ICI->getOperand(0);
+ } else if (auto *Trunc = dyn_cast<TruncInst>(BI->getCondition())) {
+ if (Trunc->hasNoUnsignedWrap())
+ CV = Trunc->getOperand(0);
}
+ }
// Unwrap any lossless ptrtoint cast.
if (CV) {
@@ -840,11 +844,20 @@ BasicBlock *SimplifyCFGOpt::getValueEqualityComparisonCases(
}
BranchInst *BI = cast<BranchInst>(TI);
- ICmpInst *ICI = cast<ICmpInst>(BI->getCondition());
- BasicBlock *Succ = BI->getSuccessor(ICI->getPredicate() == ICmpInst::ICMP_NE);
- Cases.push_back(ValueEqualityComparisonCase(
- getConstantInt(ICI->getOperand(1), DL), Succ));
- return BI->getSuccessor(ICI->getPredicate() == ICmpInst::ICMP_EQ);
+ Value *Cond = BI->getCondition();
+ ICmpInst::Predicate Pred;
+ ConstantInt *C;
+ if (auto *ICI = dyn_cast<ICmpInst>(Cond)) {
+ Pred = ICI->getPredicate();
+ C = getConstantInt(ICI->getOperand(1), DL);
+ } else {
+ Pred = ICmpInst::ICMP_NE;
+ auto *Trunc = cast<TruncInst>(Cond);
+ C = ConstantInt::get(cast<IntegerType>(Trunc->getOperand(0)->getType()), 0);
+ }
+ BasicBlock *Succ = BI->getSuccessor(Pred == ICmpInst::ICMP_NE);
+ Cases.push_back(ValueEqualityComparisonCase(C, Succ));
+ return BI->getSuccessor(Pred == ICmpInst::ICMP_EQ);
}
/// Given a vector of bb/value pairs, remove any entries
@@ -1106,7 +1119,10 @@ static void getBranchWeights(Instruction *TI,
// default weight to be the first entry.
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
assert(Weights.size() == 2);
- ICmpInst *ICI = cast<ICmpInst>(BI->getCondition());
+ auto *ICI = dyn_cast<ICmpInst>(BI->getCondition());
+ if (!ICI)
+ return;
+
if (ICI->getPredicate() == ICmpInst::ICMP_EQ)
std::swap(Weights.front(), Weights.back());
}
diff --git a/llvm/test/Transforms/SimplifyCFG/switch_create.ll b/llvm/test/Transforms/SimplifyCFG/switch_create.ll
index fe08e6be35aed..a1533bdcffb43 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch_create.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch_create.ll
@@ -1071,10 +1071,10 @@ else:
define void @trunc_nuw_i1_condition(i32 %V) {
; CHECK-LABEL: @trunc_nuw_i1_condition(
-; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[V:%.*]], 2
-; CHECK-NEXT: [[C2:%.*]] = trunc nuw i32 [[V]] to i1
-; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
-; CHECK-NEXT: br i1 [[OR_COND]], label [[F:%.*]], label [[T:%.*]]
+; CHECK-NEXT: switch i32 [[V:%.*]], label [[F:%.*]] [
+; CHECK-NEXT: i32 2, label [[T:%.*]]
+; CHECK-NEXT: i32 0, label [[T]]
+; CHECK-NEXT: ]
; CHECK: common.ret:
; CHECK-NEXT: ret void
; CHECK: T:
More information about the llvm-commits
mailing list