Yingwei Zheng 8a84b285f6
[SimplifyCFG] Eliminate dead edges of switches according to the domain of conditions (#165748)
In simplifycfg/cvp/sccp, we eliminate dead edges of switches according
to the knownbits/range info of conditions. However, these approximations
may not meet the real-world needs when the domain of condition values is
sparse. For example, if the condition can only be either -3 or 3, we
cannot prove that the condition never evaluates to 1 (knownbits:
???????1, range: [-3, 4)).
This patch adds a helper function `collectPossibleValues` to enumerate
all the possible values of V. To fix the motivating issue,
`eliminateDeadSwitchCases` will use the result to remove dead edges.

Note: In
https://discourse.llvm.org/t/missed-optimization-due-to-overflow-check/88700
I proposed a new value lattice kind to represent such values. But I find
it hard to apply because the transition becomes much complicated.

Compile-time impact looks neutral:
https://llvm-compile-time-tracker.com/compare.php?from=32d6b2139a6c8f79e074e8c6cfe0cc9e79c4c0c8&to=e47c26e3f1bf9eb062684dda4fafce58438e994b&stat=instructions:u
This patch removes many dead error-handling codes:
https://github.com/dtcxzyw/llvm-opt-benchmark/pull/3012
Closes https://github.com/llvm/llvm-project/issues/165179.
2025-11-04 20:55:33 +08:00

31 lines
1.1 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt %s -keep-loops=false -switch-to-lookup=true -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
; RUN: opt %s -passes='simplifycfg<no-keep-loops;switch-to-lookup>' -S | FileCheck %s
define void @f6() #0 {
; CHECK-LABEL: @f6(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[F1_EXIT_I:%.*]]
; CHECK: f1.exit.i:
; CHECK-NEXT: [[TOBOOL7_I:%.*]] = icmp ne i16 1, 0
; CHECK-NEXT: br label [[F1_EXIT_I]]
;
entry:
br label %for.cond.i
for.cond.i: ; preds = %f1.exit.i, %entry
switch i16 undef, label %f1.exit.i [
i16 -1, label %cond.false.i3.i
i16 1, label %cond.false.i3.i
i16 0, label %cond.false.i3.i
]
cond.false.i3.i: ; preds = %for.cond.i, %for.cond.i, %for.cond.i
br label %f1.exit.i
f1.exit.i: ; preds = %cond.false.i3.i, %for.cond.i
%cond.i4.i = phi i16 [ undef, %cond.false.i3.i ], [ 1, %for.cond.i ]
%tobool7.i = icmp ne i16 %cond.i4.i, 0
br label %for.cond.i
}