BTW, we should probably backport this to god knows how many branches. Aldy
On Tue, May 23, 2023 at 2:58 PM Aldy Hernandez <al...@redhat.com> wrote: > > [Andrew, do you remotely remember what if anything this did? It came > from a wholesale merge from our long forgotten branch, so there's no > history on the specifics of it. Not important, I'm just curious. It > was probably me high on something.] > > This patch removes a buggy special case in irange::invert which seems > to have been broken for a while, and probably never triggered because > the legacy code was handled elsewhere, and the non-legacy code was > using an int_range_max of int_range<255> which made it extremely > likely for num_ranges == 255. However, with auto-resizing ranges, > int_range_max will start off at 3 and can hit this bogus code in the > unswitching code. > > PR tree-optimization/109934 > > gcc/ChangeLog: > > * value-range.cc (irange::invert): Remove buggy special case. > > gcc/testsuite/ChangeLog: > > * gcc.dg/tree-ssa/pr109934.c: New test. > --- > gcc/testsuite/gcc.dg/tree-ssa/pr109934.c | 22 ++++++++++++++++++++++ > gcc/value-range.cc | 8 -------- > 2 files changed, 22 insertions(+), 8 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr109934.c > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr109934.c > b/gcc/testsuite/gcc.dg/tree-ssa/pr109934.c > new file mode 100644 > index 00000000000..08bd5ce95c6 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr109934.c > @@ -0,0 +1,22 @@ > +// { dg-do run } > +// { dg-options "-O3" } > + > +int printf(const char *, ...); > +short a; > +long b = 3, c; > +int d(int e) { > + switch (e) > + case 111: > + case 222: > + case 44: > + return 0; > + return e; > +} > +int main() { > + for (; a >= 0; --a) > + if (d(c + 23) - 23) > + b = 0; > + > + if (b != 3) > + __builtin_abort (); > +} > diff --git a/gcc/value-range.cc b/gcc/value-range.cc > index 45b1e655967..874a1843ebf 100644 > --- a/gcc/value-range.cc > +++ b/gcc/value-range.cc > @@ -1650,14 +1650,6 @@ irange::invert () > wide_int type_min = wi::min_value (prec, sign); > wide_int type_max = wi::max_value (prec, sign); > m_nonzero_mask = wi::minus_one (prec); > - if (m_num_ranges == m_max_ranges > - && lower_bound () != type_min > - && upper_bound () != type_max) > - { > - m_base[1] = type_max; > - m_num_ranges = 1; > - return; > - } > > // At this point, we need one extra sub-range to represent the > // inverse. > -- > 2.40.1 >