[llvm] [SimplifyCFG] Transform switch to select when common bits uniquely identify one case (PR #145233)
Gábor Spaits via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 2 08:02:28 PDT 2025
https://github.com/spaits updated https://github.com/llvm/llvm-project/pull/145233
>From 842443a801479db68d6acc65d8ecb2ea0a3dc015 Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Sun, 22 Jun 2025 15:32:07 +0200
Subject: [PATCH 01/10] Transform switch to select when common bits uniquely
identify one case
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 32 ++++++-
.../SimplifyCFG/switch-to-select-two-case.ll | 88 +++++++++++++++++++
2 files changed, 116 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 147d2060e8509..e4684eb862ca8 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6198,7 +6198,7 @@ static bool initializeUniqueCases(SwitchInst *SI, PHINode *&PHI,
// TODO: Handle switches with more than 2 cases that map to the same result.
static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
Constant *DefaultResult, Value *Condition,
- IRBuilder<> &Builder) {
+ IRBuilder<> &Builder, const DataLayout &DL) {
// If we are selecting between only two cases transform into a simple
// select or a two-way select if default is possible.
// Example:
@@ -6234,10 +6234,34 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
// case 0,2,8,10 -> Cond & 0b1..0101 == 0 ? result : default
if (isPowerOf2_32(CaseCount)) {
ConstantInt *MinCaseVal = CaseValues[0];
- // Find mininal value.
- for (auto *Case : CaseValues)
+ // In case, there are bits, that can only be present in the CaseValues we
+ // can transform the switch into a select if the conjunction of
+ // all the values uniquely identify the CaseValues.
+ APInt AndMask = APInt::getAllOnes(MinCaseVal->getBitWidth());
+
+ for (auto *Case : CaseValues) {
if (Case->getValue().slt(MinCaseVal->getValue()))
MinCaseVal = Case;
+ AndMask &= Case->getValue();
+ }
+
+ KnownBits Known = computeKnownBits(Condition, DL);
+ unsigned int ConditionWidth = Condition->getType()->getIntegerBitWidth();
+ APInt ActiveBits = APInt(ConditionWidth, Known.countMaxActiveBits(),
+ Condition->getType()->isSingleValueType());
+
+ APInt One(ConditionWidth, 1, false);
+ // To make sure, that the representation of the accepted values is
+ // actually unique we check, wheter the conjucted bits and the another
+ // conjuction with the input value will only be true for exactly CaseCount
+ // number times.
+ if ((One << ActiveBits) - (One << (ActiveBits - AndMask.popcount())) ==
+ CaseCount) {
+ Value *And = Builder.CreateAnd(Condition, AndMask);
+ Value *Cmp =
+ Builder.CreateICmpNE(And, Constant::getNullValue(And->getType()));
+ return Builder.CreateSelect(Cmp, ResultVector[0].first, DefaultResult);
+ }
// Mark the bits case number touched.
APInt BitMask = APInt::getZero(MinCaseVal->getBitWidth());
@@ -6325,7 +6349,7 @@ static bool trySwitchToSelect(SwitchInst *SI, IRBuilder<> &Builder,
assert(PHI != nullptr && "PHI for value select not found");
Builder.SetInsertPoint(SI);
Value *SelectValue =
- foldSwitchToSelect(UniqueResults, DefaultResult, Cond, Builder);
+ foldSwitchToSelect(UniqueResults, DefaultResult, Cond, Builder, DL);
if (!SelectValue)
return false;
diff --git a/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll b/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
index 50998e447b71d..638bda990bc87 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
@@ -309,3 +309,91 @@ end:
%t0 = phi i8 [ 42, %case1 ], [ 42, %case2 ], [ 44, %case3 ], [ 44, %case4 ]
ret i8 %t0
}
+
+define i1 @range0to4odd(i8 range(i8 0, 4) %f) {
+; CHECK-LABEL: @range0to4odd(
+; CHECK-NEXT: bb3:
+; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[TMP0]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ switch i8 %f, label %bb1 [
+ i8 1, label %bb2
+ i8 3, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
+define i1 @range1to4odd(i8 range(i8 1, 4) %f) {
+; CHECK-LABEL: @range1to4odd(
+; CHECK-NEXT: bb3:
+; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[TMP0]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ switch i8 %f, label %bb1 [
+ i8 1, label %bb2
+ i8 3, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
+define i1 @range0to8odd(i8 range(i8 0, 8) %f) {
+; CHECK-LABEL: @range0to8odd(
+; CHECK-NEXT: bb3:
+; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[TMP0]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ switch i8 %f, label %bb1 [
+ i8 1, label %bb2
+ i8 3, label %bb2
+ i8 5, label %bb2
+ i8 7, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
+define i1 @negative_range0to5even(i8 range(i8 0, 5) %f) {
+; CHECK-LABEL: @negative_range0to5even(
+; CHECK-NEXT: bb3:
+; CHECK-NEXT: [[TMP0:%.*]] = sub i8 [[F:%.*]], 2
+; CHECK-NEXT: [[SWITCH_AND:%.*]] = and i8 [[TMP0]], -3
+; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i8 [[SWITCH_AND]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
+; CHECK-NEXT: ret i1 [[TMP1]]
+;
+ switch i8 %f, label %bb1 [
+ i8 2, label %bb2
+ i8 4, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
>From 01d32adf40c109cfaa58fd748357f6a91b6b3a31 Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Mon, 30 Jun 2025 12:50:44 +0200
Subject: [PATCH 02/10] ActiveBits shall be unsigned regardless of the
Condition
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index e4684eb862ca8..52f6f5cbbc0f9 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6247,8 +6247,8 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
KnownBits Known = computeKnownBits(Condition, DL);
unsigned int ConditionWidth = Condition->getType()->getIntegerBitWidth();
- APInt ActiveBits = APInt(ConditionWidth, Known.countMaxActiveBits(),
- Condition->getType()->isSingleValueType());
+ APInt ActiveBits =
+ APInt(ConditionWidth, Known.countMaxActiveBits(), false);
APInt One(ConditionWidth, 1, false);
// To make sure, that the representation of the accepted values is
>From 7e323c4e6c0abb4bf0d59a7cae3e8bc4ef1f010d Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Mon, 30 Jun 2025 14:45:05 +0200
Subject: [PATCH 03/10] Generate identifier pattern using and add more tests
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 7 +-
.../SimplifyCFG/switch-to-select-two-case.ll | 101 +++++++++++++++++-
2 files changed, 101 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 52f6f5cbbc0f9..2747d6cd42026 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6255,11 +6255,10 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
// actually unique we check, wheter the conjucted bits and the another
// conjuction with the input value will only be true for exactly CaseCount
// number times.
- if ((One << ActiveBits) - (One << (ActiveBits - AndMask.popcount())) ==
- CaseCount) {
+ if ((One << (ActiveBits - AndMask.popcount())) == CaseCount) {
Value *And = Builder.CreateAnd(Condition, AndMask);
- Value *Cmp =
- Builder.CreateICmpNE(And, Constant::getNullValue(And->getType()));
+ Value *Cmp = Builder.CreateICmpEQ(
+ And, Constant::getIntegerValue(And->getType(), AndMask));
return Builder.CreateSelect(Cmp, ResultVector[0].first, DefaultResult);
}
diff --git a/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll b/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
index 638bda990bc87..0771ed1cd4bca 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
@@ -314,7 +314,7 @@ define i1 @range0to4odd(i8 range(i8 0, 4) %f) {
; CHECK-LABEL: @range0to4odd(
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 1
-; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[TMP0]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 1
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
; CHECK-NEXT: ret i1 [[TMP2]]
;
@@ -335,7 +335,7 @@ define i1 @range1to4odd(i8 range(i8 1, 4) %f) {
; CHECK-LABEL: @range1to4odd(
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 1
-; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[TMP0]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 1
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
; CHECK-NEXT: ret i1 [[TMP2]]
;
@@ -356,7 +356,7 @@ define i1 @range0to8odd(i8 range(i8 0, 8) %f) {
; CHECK-LABEL: @range0to8odd(
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 1
-; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[TMP0]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 1
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
; CHECK-NEXT: ret i1 [[TMP2]]
;
@@ -375,6 +375,101 @@ bb3:
ret i1 %_0.sroa.0.0
}
+define i1 @range0to8most_significant_bit(i8 range(i8 0, 8) %f) {
+; CHECK-LABEL: @range0to8most_significant_bit(
+; CHECK-NEXT: bb3:
+; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 4
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 4
+; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ switch i8 %f, label %bb1 [
+ i8 4, label %bb2
+ i8 5, label %bb2
+ i8 6, label %bb2
+ i8 7, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
+define i1 @range0to15_middle_two_bits(i8 range(i8 0, 16) %f) {
+; CHECK-LABEL: @range0to15_middle_two_bits(
+; CHECK-NEXT: bb3:
+; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 6
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 6
+; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ switch i8 %f, label %bb1 [
+ i8 6, label %bb2
+ i8 7, label %bb2
+ i8 14, label %bb2
+ i8 15, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
+define i1 @negative_range0to15(i8 range(i8 0, 16) %f) {
+; CHECK-LABEL: @negative_range0to15(
+; CHECK-NEXT: switch i8 [[F:%.*]], label [[BB3:%.*]] [
+; CHECK-NEXT: i8 6, label [[BB2:%.*]]
+; CHECK-NEXT: i8 7, label [[BB2]]
+; CHECK-NEXT: i8 14, label [[BB2]]
+; CHECK-NEXT: ]
+; CHECK: bb2:
+; CHECK-NEXT: br label [[BB3]]
+; CHECK: bb3:
+; CHECK-NEXT: [[_0_SROA_0_0:%.*]] = phi i1 [ true, [[BB2]] ], [ false, [[TMP0:%.*]] ]
+; CHECK-NEXT: ret i1 [[_0_SROA_0_0]]
+;
+ switch i8 %f, label %bb1 [
+ i8 6, label %bb2
+ i8 7, label %bb2
+ i8 14, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
+define i1 @negative_range0to15_pow_2(i8 range(i8 0, 16) %f) {
+; CHECK-LABEL: @negative_range0to15_pow_2(
+; CHECK-NEXT: bb3:
+; CHECK-NEXT: [[TMP0:%.*]] = sub i8 [[F:%.*]], 6
+; CHECK-NEXT: [[SWITCH_AND:%.*]] = and i8 [[TMP0]], -2
+; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i8 [[SWITCH_AND]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
+; CHECK-NEXT: ret i1 [[TMP1]]
+;
+ switch i8 %f, label %bb1 [
+ i8 6, label %bb2
+ i8 7, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
define i1 @negative_range0to5even(i8 range(i8 0, 5) %f) {
; CHECK-LABEL: @negative_range0to5even(
; CHECK-NEXT: bb3:
>From 3441ff234403adf0fe25203eaea9c963e7515d24 Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Tue, 1 Jul 2025 10:50:24 +0200
Subject: [PATCH 04/10] unsigned int -> unsigned
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 2747d6cd42026..9747d985baf27 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6246,7 +6246,7 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
}
KnownBits Known = computeKnownBits(Condition, DL);
- unsigned int ConditionWidth = Condition->getType()->getIntegerBitWidth();
+ unsigned ConditionWidth = Condition->getType()->getIntegerBitWidth();
APInt ActiveBits =
APInt(ConditionWidth, Known.countMaxActiveBits(), false);
>From 4e8789a4871dbd16e24cb1c9c13347442aba6d64 Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Tue, 1 Jul 2025 13:57:05 +0200
Subject: [PATCH 05/10] Use new way to compute if pattern identifies all
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 32 ++++++++++++-----------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 9747d985baf27..61caac76a8c24 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6239,27 +6239,29 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
// all the values uniquely identify the CaseValues.
APInt AndMask = APInt::getAllOnes(MinCaseVal->getBitWidth());
+ // Find mininal value and compute the conjuction of the values.
for (auto *Case : CaseValues) {
if (Case->getValue().slt(MinCaseVal->getValue()))
MinCaseVal = Case;
AndMask &= Case->getValue();
}
- KnownBits Known = computeKnownBits(Condition, DL);
- unsigned ConditionWidth = Condition->getType()->getIntegerBitWidth();
- APInt ActiveBits =
- APInt(ConditionWidth, Known.countMaxActiveBits(), false);
-
- APInt One(ConditionWidth, 1, false);
- // To make sure, that the representation of the accepted values is
- // actually unique we check, wheter the conjucted bits and the another
- // conjuction with the input value will only be true for exactly CaseCount
- // number times.
- if ((One << (ActiveBits - AndMask.popcount())) == CaseCount) {
- Value *And = Builder.CreateAnd(Condition, AndMask);
- Value *Cmp = Builder.CreateICmpEQ(
- And, Constant::getIntegerValue(And->getType(), AndMask));
- return Builder.CreateSelect(Cmp, ResultVector[0].first, DefaultResult);
+ if (!AndMask.isZero()) {
+ KnownBits Known = computeKnownBits(Condition, DL);
+ // Compute the number of bits that are free to vary.
+ unsigned FreeBits = Known.countMaxActiveBits() - AndMask.popcount();
+ // Compute 2^FreeBits in order to check whether all the possible
+ // combination of the free bits matches the number of cases.
+ APInt TopBit = APInt::getOneBitSet(
+ Condition->getType()->getIntegerBitWidth(), FreeBits);
+
+ if (TopBit == CaseCount) {
+ Value *And = Builder.CreateAnd(Condition, AndMask);
+ Value *Cmp = Builder.CreateICmpEQ(
+ And, Constant::getIntegerValue(And->getType(), AndMask));
+ return Builder.CreateSelect(Cmp, ResultVector[0].first,
+ DefaultResult);
+ }
}
// Mark the bits case number touched.
>From 74fe0fee9d6336f3991b7d2a249551f41d9db5d0 Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Tue, 1 Jul 2025 14:10:08 +0200
Subject: [PATCH 06/10] Add out of range tests
---
.../SimplifyCFG/switch-to-select-two-case.ll | 105 ++++++++++++++++++
1 file changed, 105 insertions(+)
diff --git a/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll b/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
index 0771ed1cd4bca..eea52211e33f2 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
@@ -492,3 +492,108 @@ bb3:
ret i1 %_0.sroa.0.0
}
+define i1 @range0to15_out_of_range_non_prime(i8 range(i8 0, 16) %f) {
+; CHECK-LABEL: @range0to15_out_of_range_non_prime(
+; CHECK-NEXT: bb3:
+; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 6
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 6
+; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ switch i8 %f, label %bb1 [
+ i8 6, label %bb2
+ i8 7, label %bb2
+ i8 14, label %bb2
+ i8 15, label %bb2
+ i8 22, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
+define i1 @range0to15_out_of_range_non_prime_more(i8 range(i8 0, 16) %f) {
+; CHECK-LABEL: @range0to15_out_of_range_non_prime_more(
+; CHECK-NEXT: bb3:
+; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 6
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 6
+; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ switch i8 %f, label %bb1 [
+ i8 6, label %bb2
+ i8 7, label %bb2
+ i8 14, label %bb2
+ i8 15, label %bb2
+ i8 22, label %bb2
+ i8 23, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
+define i1 @negative_range0to15_out_of_range_non_prime(i8 range(i8 0, 16) %f) {
+; CHECK-LABEL: @negative_range0to15_out_of_range_non_prime(
+; CHECK-NEXT: switch i8 [[F:%.*]], label [[BB3:%.*]] [
+; CHECK-NEXT: i8 6, label [[BB2:%.*]]
+; CHECK-NEXT: i8 14, label [[BB2]]
+; CHECK-NEXT: i8 15, label [[BB2]]
+; CHECK-NEXT: ]
+; CHECK: bb2:
+; CHECK-NEXT: br label [[BB3]]
+; CHECK: bb3:
+; CHECK-NEXT: [[TMP2:%.*]] = phi i1 [ true, [[BB2]] ], [ false, [[TMP0:%.*]] ]
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ switch i8 %f, label %bb1 [
+ i8 6, label %bb2
+ i8 14, label %bb2
+ i8 15, label %bb2
+ i8 23, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
+define i1 @negative_range0to15_out_of_range(i8 range(i8 0, 16) %f) {
+; CHECK-LABEL: @negative_range0to15_out_of_range(
+; CHECK-NEXT: switch i8 [[F:%.*]], label [[BB3:%.*]] [
+; CHECK-NEXT: i8 6, label [[BB2:%.*]]
+; CHECK-NEXT: i8 7, label [[BB2]]
+; CHECK-NEXT: i8 14, label [[BB2]]
+; CHECK-NEXT: ]
+; CHECK: bb2:
+; CHECK-NEXT: br label [[BB3]]
+; CHECK: bb3:
+; CHECK-NEXT: [[_0_SROA_0_0:%.*]] = phi i1 [ true, [[BB2]] ], [ false, [[TMP0:%.*]] ]
+; CHECK-NEXT: ret i1 [[_0_SROA_0_0]]
+;
+ switch i8 %f, label %bb1 [
+ i8 6, label %bb2
+ i8 7, label %bb2
+ i8 14, label %bb2
+ i8 150, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
>From 9ff18fcbec9945721ebe65f83741fc94a96cd002 Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Tue, 1 Jul 2025 15:29:08 +0200
Subject: [PATCH 07/10] All out of range case
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 4 ++--
.../SimplifyCFG/switch-to-select-two-case.ll | 23 +++++++++++++++++++
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 61caac76a8c24..40355c210b2d5 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6245,9 +6245,9 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
MinCaseVal = Case;
AndMask &= Case->getValue();
}
+ KnownBits Known = computeKnownBits(Condition, DL);
- if (!AndMask.isZero()) {
- KnownBits Known = computeKnownBits(Condition, DL);
+ if (!AndMask.isZero() && Known.getMaxValue().uge(AndMask)) {
// Compute the number of bits that are free to vary.
unsigned FreeBits = Known.countMaxActiveBits() - AndMask.popcount();
// Compute 2^FreeBits in order to check whether all the possible
diff --git a/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll b/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
index eea52211e33f2..890d6c25f2a1d 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
@@ -492,6 +492,9 @@ bb3:
ret i1 %_0.sroa.0.0
}
+; Out of range scenarios. Check if the cases, that have a value out of range
+; are eliminated and the optimization is performed.
+
define i1 @range0to15_out_of_range_non_prime(i8 range(i8 0, 16) %f) {
; CHECK-LABEL: @range0to15_out_of_range_non_prime(
; CHECK-NEXT: bb3:
@@ -597,3 +600,23 @@ bb3:
ret i1 %_0.sroa.0.0
}
+define i1 @negative_range0to15_all_out_of_range(i8 range(i8 0, 16) %f) {
+; CHECK-LABEL: @negative_range0to15_all_out_of_range(
+; CHECK-NEXT: bb1:
+; CHECK-NEXT: ret i1 false
+;
+ switch i8 %f, label %bb1 [
+ i8 22, label %bb2
+ i8 23, label %bb2
+ i8 30, label %bb2
+ i8 31, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
>From 4591fe7d854bea73151a13f9f536b8a653a00911 Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Tue, 1 Jul 2025 15:45:21 +0200
Subject: [PATCH 08/10] Extend testing
---
.../SimplifyCFG/switch-to-select-two-case.ll | 131 ++++++++++++++++++
1 file changed, 131 insertions(+)
diff --git a/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll b/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
index 890d6c25f2a1d..39d774f6ffb5c 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
@@ -310,6 +310,96 @@ end:
ret i8 %t0
}
+define i1 @no_range(i8 %f) {
+; CHECK-LABEL: @no_range(
+; CHECK-NEXT: bb3:
+; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[F:%.*]], 60
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 60
+; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i1 true, i1 false
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ switch i8 %f, label %bb1 [
+ i8 60, label %bb2
+ i8 61, label %bb2
+ i8 62, label %bb2
+ i8 63, label %bb2
+ i8 124, label %bb2
+ i8 188, label %bb2
+ i8 252, label %bb2
+ i8 189, label %bb2
+ i8 190, label %bb2
+ i8 191, label %bb2
+ i8 125, label %bb2
+ i8 126, label %bb2
+ i8 127, label %bb2
+ i8 253, label %bb2
+ i8 254, label %bb2
+ i8 255, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
+define i1 @negative_no_range(i8 %f) {
+; CHECK-LABEL: @negative_no_range(
+; CHECK-NEXT: switch i8 [[F:%.*]], label [[BB3:%.*]] [
+; CHECK-NEXT: i8 52, label [[BB2:%.*]]
+; CHECK-NEXT: i8 61, label [[BB2]]
+; CHECK-NEXT: i8 62, label [[BB2]]
+; CHECK-NEXT: i8 63, label [[BB2]]
+; CHECK-NEXT: i8 124, label [[BB2]]
+; CHECK-NEXT: i8 -68, label [[BB2]]
+; CHECK-NEXT: i8 -4, label [[BB2]]
+; CHECK-NEXT: i8 -67, label [[BB2]]
+; CHECK-NEXT: i8 -66, label [[BB2]]
+; CHECK-NEXT: i8 -65, label [[BB2]]
+; CHECK-NEXT: i8 125, label [[BB2]]
+; CHECK-NEXT: i8 126, label [[BB2]]
+; CHECK-NEXT: i8 127, label [[BB2]]
+; CHECK-NEXT: i8 -3, label [[BB2]]
+; CHECK-NEXT: i8 -2, label [[BB2]]
+; CHECK-NEXT: i8 -1, label [[BB2]]
+; CHECK-NEXT: ]
+; CHECK: bb2:
+; CHECK-NEXT: br label [[BB3]]
+; CHECK: bb3:
+; CHECK-NEXT: [[_0_SROA_0_0:%.*]] = phi i1 [ true, [[BB2]] ], [ false, [[TMP0:%.*]] ]
+; CHECK-NEXT: ret i1 [[_0_SROA_0_0]]
+;
+ switch i8 %f, label %bb1 [
+ i8 52, label %bb2
+ i8 61, label %bb2
+ i8 62, label %bb2
+ i8 63, label %bb2
+ i8 124, label %bb2
+ i8 188, label %bb2
+ i8 252, label %bb2
+ i8 189, label %bb2
+ i8 190, label %bb2
+ i8 191, label %bb2
+ i8 125, label %bb2
+ i8 126, label %bb2
+ i8 127, label %bb2
+ i8 253, label %bb2
+ i8 254, label %bb2
+ i8 255, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
+; Using ranges.
+
define i1 @range0to4odd(i8 range(i8 0, 4) %f) {
; CHECK-LABEL: @range0to4odd(
; CHECK-NEXT: bb3:
@@ -492,6 +582,47 @@ bb3:
ret i1 %_0.sroa.0.0
}
+define i1 @range0to15_corner_case(i8 range(i8 0, 16) %f) {
+; CHECK-LABEL: @range0to15_corner_case(
+; CHECK-NEXT: bb3:
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[F:%.*]], 15
+; CHECK-NEXT: [[DOT:%.*]] = select i1 [[COND]], i1 true, i1 false
+; CHECK-NEXT: ret i1 [[DOT]]
+;
+ switch i8 %f, label %bb1 [
+ i8 15, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
+define i1 @negative_range0to15_corner_case(i8 range(i8 0, 16) %f) {
+; CHECK-LABEL: @negative_range0to15_corner_case(
+; CHECK-NEXT: bb3:
+; CHECK-NEXT: [[SWITCH_SELECTCMP_CASE1:%.*]] = icmp eq i8 [[F:%.*]], 15
+; CHECK-NEXT: [[SWITCH_SELECTCMP_CASE2:%.*]] = icmp eq i8 [[F]], 8
+; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = or i1 [[SWITCH_SELECTCMP_CASE1]], [[SWITCH_SELECTCMP_CASE2]]
+; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
+; CHECK-NEXT: ret i1 [[TMP0]]
+;
+ switch i8 %f, label %bb1 [
+ i8 15, label %bb2
+ i8 8, label %bb2
+ ]
+bb1:
+ br label %bb3
+bb2:
+ br label %bb3
+bb3:
+ %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %_0.sroa.0.0
+}
+
; Out of range scenarios. Check if the cases, that have a value out of range
; are eliminated and the optimization is performed.
>From 33f4a037dea686bab320ab582b0be7394de37441 Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Tue, 1 Jul 2025 16:00:48 +0200
Subject: [PATCH 09/10] Address review findings
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 8 +--
.../SimplifyCFG/switch-to-select-two-case.ll | 69 +++++++++----------
2 files changed, 38 insertions(+), 39 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 40355c210b2d5..ef1c74f766f20 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6234,12 +6234,12 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
// case 0,2,8,10 -> Cond & 0b1..0101 == 0 ? result : default
if (isPowerOf2_32(CaseCount)) {
ConstantInt *MinCaseVal = CaseValues[0];
- // In case, there are bits, that can only be present in the CaseValues we
+ // If there are bits that are set exclusively by CaseValues, we
// can transform the switch into a select if the conjunction of
- // all the values uniquely identify the CaseValues.
+ // all the values uniquely identify CaseValues.
APInt AndMask = APInt::getAllOnes(MinCaseVal->getBitWidth());
- // Find mininal value and compute the conjuction of the values.
+ // Find the minimum value and compute the and of all the case values.
for (auto *Case : CaseValues) {
if (Case->getValue().slt(MinCaseVal->getValue()))
MinCaseVal = Case;
@@ -6251,7 +6251,7 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
// Compute the number of bits that are free to vary.
unsigned FreeBits = Known.countMaxActiveBits() - AndMask.popcount();
// Compute 2^FreeBits in order to check whether all the possible
- // combination of the free bits matches the number of cases.
+ // combinations of the free bits matches the number of cases.
APInt TopBit = APInt::getOneBitSet(
Condition->getType()->getIntegerBitWidth(), FreeBits);
diff --git a/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll b/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
index 39d774f6ffb5c..fe2e897125eb8 100644
--- a/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
+++ b/llvm/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
@@ -341,8 +341,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
define i1 @negative_no_range(i8 %f) {
@@ -394,8 +394,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
; Using ranges.
@@ -417,8 +417,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
define i1 @range1to4odd(i8 range(i8 1, 4) %f) {
@@ -438,8 +438,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
define i1 @range0to8odd(i8 range(i8 0, 8) %f) {
@@ -461,8 +461,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
define i1 @range0to8most_significant_bit(i8 range(i8 0, 8) %f) {
@@ -484,8 +484,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
define i1 @range0to15_middle_two_bits(i8 range(i8 0, 16) %f) {
@@ -507,8 +507,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
define i1 @negative_range0to15(i8 range(i8 0, 16) %f) {
@@ -534,8 +534,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
define i1 @negative_range0to15_pow_2(i8 range(i8 0, 16) %f) {
@@ -556,8 +556,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
define i1 @negative_range0to5even(i8 range(i8 0, 5) %f) {
@@ -578,8 +578,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
define i1 @range0to15_corner_case(i8 range(i8 0, 16) %f) {
@@ -597,8 +597,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
define i1 @negative_range0to15_corner_case(i8 range(i8 0, 16) %f) {
@@ -619,8 +619,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
; Out of range scenarios. Check if the cases, that have a value out of range
@@ -646,8 +646,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
define i1 @range0to15_out_of_range_non_prime_more(i8 range(i8 0, 16) %f) {
@@ -671,8 +671,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
define i1 @negative_range0to15_out_of_range_non_prime(i8 range(i8 0, 16) %f) {
@@ -699,8 +699,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
define i1 @negative_range0to15_out_of_range(i8 range(i8 0, 16) %f) {
@@ -727,8 +727,8 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
define i1 @negative_range0to15_all_out_of_range(i8 range(i8 0, 16) %f) {
@@ -747,7 +747,6 @@ bb1:
bb2:
br label %bb3
bb3:
- %_0.sroa.0.0 = phi i1 [ false, %bb1 ], [ true, %bb2 ]
- ret i1 %_0.sroa.0.0
+ %phi = phi i1 [ false, %bb1 ], [ true, %bb2 ]
+ ret i1 %phi
}
-
>From dc81b9bc5a8f4b6ca2a440100d96c9ca6ae9c0f8 Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Wed, 2 Jul 2025 17:02:08 +0200
Subject: [PATCH 10/10] Use Log3_32
---
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index ef1c74f766f20..a75f29000ca18 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6250,12 +6250,10 @@ static Value *foldSwitchToSelect(const SwitchCaseResultVectorTy &ResultVector,
if (!AndMask.isZero() && Known.getMaxValue().uge(AndMask)) {
// Compute the number of bits that are free to vary.
unsigned FreeBits = Known.countMaxActiveBits() - AndMask.popcount();
- // Compute 2^FreeBits in order to check whether all the possible
- // combinations of the free bits matches the number of cases.
- APInt TopBit = APInt::getOneBitSet(
- Condition->getType()->getIntegerBitWidth(), FreeBits);
- if (TopBit == CaseCount) {
+ // Check if the number of values covered by the mask is equal
+ // to the number of cases.
+ if (FreeBits == Log2_32(CaseCount)) {
Value *And = Builder.CreateAnd(Condition, AndMask);
Value *Cmp = Builder.CreateICmpEQ(
And, Constant::getIntegerValue(And->getType(), AndMask));
More information about the llvm-commits
mailing list