https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92005
--- Comment #2 from Peter Dimov <pdimov at gmail dot com> --- r276416 makes -O2 inline less, and -O3 does fix this specific case. However, there appears to be some deeper issue here. I've reduced the number of cases from 10 to 5 for the example, but when I increase them back to 10 as in https://godbolt.org/z/VyCeWQ, gcc 9.2 still generates a simple lookup table at -O2, whereas gcc 10 generates a jump table even at -O3: https://godbolt.org/z/qJqNDh. ``` template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; struct T0 {}; struct T1 {}; struct T2 {}; struct T3 {}; struct T4 {}; struct T5 {}; struct T6 {}; struct T7 {}; struct T8 {}; struct T9 {}; struct variant { unsigned index_; union { T0 t0_; T1 t1_; T2 t2_; T3 t3_; T4 t4_; T5 t5_; T6 t6_; T7 t7_; T8 t8_; T9 t9_; }; }; template<class F> int visit( F f, variant const& v ) { switch( v.index_ ) { case 0: return f( v.t0_ ); case 1: return f( v.t1_ ); case 2: return f( v.t2_ ); case 3: return f( v.t3_ ); case 4: return f( v.t4_ ); case 5: return f( v.t5_ ); case 6: return f( v.t6_ ); case 7: return f( v.t7_ ); case 8: return f( v.t8_ ); case 9: return f( v.t9_ ); default: __builtin_unreachable(); } } int do_visit(variant const& v) { return visit(overloaded{ [](T0 val) { return 3; }, [](T1 val) { return 5; }, [](T2 val) { return 8; }, [](T3 val) { return 9; }, [](T4 val) { return 10; }, [](T5 val) { return 11; }, [](T6 val) { return 12; }, [](T7 val) { return 13; }, [](T8 val) { return 14; }, [](T9 val) { return 233; } }, v); } ```