[llvm] [SimplifyCFG] Fold the contiguous wrapping cases into ICmp. (PR #161000)

Antonio Frighetto via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 3 06:36:55 PDT 2025


================
@@ -5718,15 +5718,49 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
   return Changed;
 }
 
-static bool casesAreContiguous(SmallVectorImpl<ConstantInt *> &Cases) {
+static bool casesAreContiguous(Value *Condition,
+                               SmallVectorImpl<ConstantInt *> &Cases,
+                               ConstantInt *&ContiguousCasesMin,
+                               ConstantInt *&ContiguousCasesMax,
+                               bool &IsWrapping) {
   assert(Cases.size() >= 1);
 
   array_pod_sort(Cases.begin(), Cases.end(), constantIntSortPredicate);
-  for (size_t I = 1, E = Cases.size(); I != E; ++I) {
-    if (Cases[I - 1]->getValue() != Cases[I]->getValue() + 1)
+  auto Min = Cases.back()->getValue();
+  auto Max = Cases.front()->getValue();
+  auto Offset = Max - Min;
+  auto ContiguousOffset = Cases.size() - 1;
+  if (Offset == ContiguousOffset) {
+    ContiguousCasesMin = Cases.back();
+    ContiguousCasesMax = Cases.front();
+    return true;
+  }
+  ConstantRange CR = computeConstantRange(Condition, /*ForSigned=*/false);
+  // If this is a wrapping contiguous range, that is, [Min, OtherMin] +
+  // [OtherMax, Max] (also [OtherMax, OtherMin]), [OtherMin+1, OtherMax-1] is a
+  // contiguous range for the other destination. N.B. If CR is not a full range,
+  // Max+1 is not equal to Min. It's not continuous in arithmetic.
+  if (Max == CR.getUnsignedMax() && Min == CR.getUnsignedMin()) {
+    assert(Cases.size() >= 2);
+    auto *It =
----------------
antoniofrighetto wrote:

(I meant this before the std::adjacent_find, which is not appearing)

https://github.com/llvm/llvm-project/pull/161000


More information about the llvm-commits mailing list