[SimplifyCFG] Improve range reducing for switches by dtcxzyw · Pull Request #67882 · llvm/llvm-project (original) (raw)

@llvm/pr-subscribers-llvm-transforms

Changes

This patch improves range reducing for switches when the default block is unreachable.
It will mask out the common high bits and move the largest hole to the back.

Example:

int f1(int x) {
  switch (x) {
    case 0: return 1;
    case 1: return 2;
    case 255: return 0;
    default: __builtin_unreachable();
  }
}

after range reduction:

int f1(int x) {
  switch ((x + 1) & 255) {
    case 1: return 1;
    case 2: return 2;
    case 0: return 0;
    default: __builtin_unreachable();
  }
}

Fixes #67842.


Full diff: https://github.com/llvm/llvm-project/pull/67882.diff

2 Files Affected:

diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 35fead111aa9666..ef7a8d34b539662 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -80,6 +80,7 @@ #include #include #include +#include #include #include #include @@ -6748,6 +6749,71 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder, return true; }

+/// Try to reduce the range of cases with an unreachable default. +static bool +ReduceSwitchRangeWithUnreachableDefault(SwitchInst *SI,

@@ -6786,6 +6851,9 @@ static bool ReduceSwitchRange(SwitchInst *SI, IRBuilder<> &Builder, for (auto &V : Values) V -= (uint64_t)(Base);

+define i8 @pr67842(i32 %0) { +; CHECK-LABEL: @pr67842( +; CHECK-NEXT: start: +; CHECK-NEXT: [[TMP1:%.]] = add i32 [[TMP0:%.]], 1 +; CHECK-NEXT: [[TMP2:%.]] = and i32 [[TMP1]], 255 +; CHECK-NEXT: [[SWITCH_IDX_CAST:%.]] = trunc i32 [[TMP2]] to i8 +; CHECK-NEXT: [[SWITCH_OFFSET:%.*]] = add nsw i8 [[SWITCH_IDX_CAST]], -1 +; CHECK-NEXT: ret i8 [[SWITCH_OFFSET]] +; +start: