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.

Reply via email to