https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245
--- Comment #9 from rguenther at suse dot de <rguenther at suse dot de> --- On December 14, 2020 12:19:32 PM GMT+01:00, "jakub at gcc dot gnu.org" <gcc-bugzi...@gcc.gnu.org> wrote: >https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96245 > >--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- >Looking at godbolt and LLVM release notes, this optimization appeared >in LLVM 9 >and looks to be a switch optimization: > >LLVM can now sink similar instructions to a common successor block also >when >the instructions have no uses, such as calls to void functions. This >allows >code such as > >void g(int); >enum e { A, B, C, D }; >void f(e x, int y, int z) { > switch(x) { > case A: g(6); break; > case B: g(3); break; > case C: g(9); break; > case D: g(2); break; > } >} > >to be optimized to a single call to g, with the argument loaded from a >lookup >table. >I bet it is https://reviews.llvm.org/D59936 > >We don't optimize even: >void >foo (int *p, int x) >{ > switch (x) > { > case 7: *p = 14; break; > case 8: *p = 15; break; > case 9: *p = 16; break; > case 10: *p = 17; break; > case 11: *p = 18; break; > case 12: *p = 19; break; > default: return; > } >} Store commoning in the sink pass should do this. But it would need to create a forwarder because of the default case. That's a missed piece there. >but do optimize if one performs the switch parametrized tail merging >manually: >void >bar (int *p, int x) >{ > int y; > switch (x) > { > case 7: y = 14; break; > case 8: y = 15; break; > case 9: y = 16; break; > case 10: y = 17; break; > case 11: y = 18; break; > case 12: y = 19; break; > default: return; > } > *p = y; >} > >So, do you prefer to do this in tree-ssa-tail-merge.c (for blocks >starting with >switches) or in tree-switch-conversion.c, and should we handle both the >case >where the constant(s) are linear vs. the switch expression, or also any >other >(let the switchconv pass then create the arrays)?