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 }