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
}