https://godbolt.org/g/VvrbFZ For the code below generated assembly is the worst possible - test 1, else test 3, else test 2 with expected value of 2 last ... Whats going on? long case_2(); long case_3(); long case_1(); long case_else(); long test(long a) { switch (__builtin_expect(a, 2)) { case 2: return case_2(); case 3: return case_3(); case 1: return case_1(); case 0: case 4: case 5: return case_else(); default: __builtin_unreachable(); } }
On x86-64, clang-trunk at least checks for the expected case first: https://godbolt.org/g/mEfQ4e. What changed? Well bisection results show that this was fixed by r300440: [llvm] [mirror/master] [BPI] Use metadata info before any other heuristics But the gcc 7 snapshot produces a lookup table. That might be better. CC'ing Marcello and Hans to comment, since IIRC they have both worked on switch lowering. best vedant> On Apr 18, 2017, at 4:20 PM, Adam Nowacki via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > https://godbolt.org/g/VvrbFZ > > For the code below generated assembly is the worst possible - test 1, else test 3, else test 2 with expected value of 2 last ... Whats going on? > > long case_2(); > long case_3(); > long case_1(); > long case_else(); > long test(long a) { > switch (__builtin_expect(a, 2)) { > case 2: return case_2(); > case 3: return case_3(); > case 1: return case_1(); > case 0: > case 4: > case 5: return case_else(); > default: __builtin_unreachable(); > } > } > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
GCC produces a jump table. Clang doesn't do that for switches with fewer than 4 cases (the example code effectively has cases 1, 2, 3 and the "else case"). I don't know if that cut-off is optimal, but it's not entirely obvious that a jump table would be better in this case. On Mon, Apr 24, 2017 at 2:41 PM, Vedant Kumar <vsk at apple.com> wrote:> > On x86-64, clang-trunk at least checks for the expected case first: > > https://godbolt.org/g/mEfQ4e. > > What changed? Well bisection results show that this was fixed by r300440: > > [llvm] [mirror/master] [BPI] Use metadata info before any other heuristics > > But the gcc 7 snapshot produces a lookup table. That might be better. CC'ing Marcello and Hans to comment, since IIRC they have both worked on switch lowering. > > best > vedant > > > On Apr 18, 2017, at 4:20 PM, Adam Nowacki via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > > > https://godbolt.org/g/VvrbFZ > > > > For the code below generated assembly is the worst possible - test 1, else test 3, else test 2 with expected value of 2 last ... Whats going on? > > > > long case_2(); > > long case_3(); > > long case_1(); > > long case_else(); > > long test(long a) { > > switch (__builtin_expect(a, 2)) { > > case 2: return case_2(); > > case 3: return case_3(); > > case 1: return case_1(); > > case 0: > > case 4: > > case 5: return case_else(); > > default: __builtin_unreachable(); > > } > > } > > _______________________________________________ > > LLVM Developers mailing list > > llvm-dev at lists.llvm.org > > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >
Yes, the switch lowering code doesn't handle when the fall-through is the most likely case. On Mon, Apr 24, 2017 at 3:27 PM, Adam Nowacki <nowak at tepeserwery.pl> wrote:> Looks only partially fixed. If expected value is for fallthrough case (either 0, 4 or 5) there are still 3 comparisons to reach it. > > On 2017-04-24 23:41, Vedant Kumar wrote: >> On x86-64, clang-trunk at least checks for the expected case first: >> >> https://godbolt.org/g/mEfQ4e. >> >> What changed? Well bisection results show that this was fixed by r300440: >> >> [llvm] [mirror/master] [BPI] Use metadata info before any other heuristics >> >> But the gcc 7 snapshot produces a lookup table. That might be better. CC'ing Marcello and Hans to comment, since IIRC they have both worked on switch lowering. >> >> best >> vedant >> >>> On Apr 18, 2017, at 4:20 PM, Adam Nowacki via llvm-dev <llvm-dev at lists.llvm.org> wrote: >>> >>> https://godbolt.org/g/VvrbFZ >>> >>> For the code below generated assembly is the worst possible - test 1, else test 3, else test 2 with expected value of 2 last ... Whats going on? >>> >>> long case_2(); >>> long case_3(); >>> long case_1(); >>> long case_else(); >>> long test(long a) { >>> switch (__builtin_expect(a, 2)) { >>> case 2: return case_2(); >>> case 3: return case_3(); >>> case 1: return case_1(); >>> case 0: >>> case 4: >>> case 5: return case_else(); >>> default: __builtin_unreachable(); >>> } >>> } >>> _______________________________________________ >>> LLVM Developers mailing list >>> llvm-dev at lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>