https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128356
--- Comment #1 from liu zhenyu <lzy20000419 at outlook dot com> --- - tree-ssa-loop-unswitch.cc:596-626 (find_unswitching_predicates_for_bb) builds the edge range with `edge_range[...].union_ (lab_range)`. The 256 case values need 256 sub-ranges, but an irange holds at most 255 (HARD_MAX_RANGES); irange::union_ then merges the last sub-ranges into one (value-range.cc:1316-1318 / :1452-1455), so the edge range becomes a superset: [0,0][2,2]...[508,510] includes 509. - unswitch_predicate's switch constructor, tree-ssa-loop-unswitch.cc:117-120, sets `false_range = true_range; false_range.invert ();`. Inverting a superset gives a subset of the real "not taken" set, so 509 is missing from false_range. - In the copy where the edge is not taken, evaluate_control_stmt_using_entry_checks (:735-738 for a gcond, :766-771 for a switch) uses that false_range as the range of `a` and folds `a == 509` to false (or drops the `case 509` edge). - The code assumes the edge range is exact; ranges are only guaranteed to be supersets, which is safe for true_range but not for its inverse.
