https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87416

            Bug ID: 87416
           Summary: [8/9 Regression] switchconv: detect identity lookup
                    arrays
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: amonakov at gcc dot gnu.org
  Target Milestone: ---

Starting from gcc-8 the following function is no longer optimized to a simple
register copy:

int foo(int how)
{
  switch (how) {
    case 0: how = 0; break;
    case 1: how = 1; break;
    case 2: how = 2; break;
  }
  return how;
}

The reason is now switchconv pass manages to transform this to an array lookup
(nice!), but misses that the array is trivial. Previously switchconv didn't
touch the switch, and late gimple passes managed to simplify it.

I think it's not too costly to have a check in switchconv that helper array is
holding an identity map and emit a copy/conversion instead of array lookup.

Although the test looks artificial, such code appears in Python (and similar
code may appear elsewhere). In posixmodule.c it has:

    /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
    switch (how) {
        case 0: how = SEEK_SET; break;
        case 1: how = SEEK_CUR; break;
        case 2: how = SEEK_END; break;
    }

and in fileio.c it has a more elaborate hand-optimized variant:

    /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
    switch (whence) {
#if SEEK_SET != 0
    case 0: whence = SEEK_SET; break;
#endif
#if SEEK_CUR != 1
    case 1: whence = SEEK_CUR; break;
#endif
#if SEEK_END != 2
    case 2: whence = SEEK_END; break;
#endif
    }

Reply via email to