[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
Tue Jul 1 05:14:21 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 1/6] 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 2/6] 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 3/6] 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 4/6] 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 5/6] 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 6/6] 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
+}
+



More information about the llvm-commits mailing list