public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/98649] New: Trivial jump table not eliminated
@ 2021-01-13  1:42 pdimov at gmail dot com
  2021-01-13  5:35 ` [Bug middle-end/98649] " pinskia at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: pdimov at gmail dot com @ 2021-01-13  1:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98649

            Bug ID: 98649
           Summary: Trivial jump table not eliminated
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pdimov at gmail dot com
  Target Milestone: ---

Trivial jump tables where all entries are the same are sometimes not
eliminated. E.g. the following example

```
struct Base { virtual void run( float f ) = 0; };
struct T0: Base { void run( float f ); };
struct T1: Base { void run( float f ); };
struct T2: Base { void run( float f ); };
struct T3: Base { void run( float f ); };
struct T4: Base { void run( float f ); };

template<int I> struct mp_int {};

struct variant
{
    unsigned index_;

    union
    {
        T0 t0_;
        T1 t1_;
        T2 t2_;
        T3 t3_;
        T4 t4_;
    };

    T0& get( mp_int<0> ) { return t0_; }
    T1& get( mp_int<1> ) { return t1_; }
    T2& get( mp_int<2> ) { return t2_; }
    T3& get( mp_int<3> ) { return t3_; }
    T4& get( mp_int<4> ) { return t4_; }
};

template<int I> decltype(auto) get( variant& v )
{
    return v.get( mp_int<I>() );
}

void f1( variant& v, float f )
{
    switch( v.index_ )
    {
        case 0: get<0>(v).run( f ); break;
        case 1: get<1>(v).run( f ); break;
        case 2: get<2>(v).run( f ); break;
        case 3: get<3>(v).run( f ); break;
        case 4: get<4>(v).run( f ); break;
        default: __builtin_unreachable();
    }
}

```

(https://godbolt.org/z/MxzGh8)

results in

```
f1(variant&, float):
        mov     eax, DWORD PTR [rdi]
        lea     r8, [rdi+8]
        jmp     [QWORD PTR .L4[0+rax*8]]
.L4:
        .quad   .L3
        .quad   .L3
        .quad   .L3
        .quad   .L3
        .quad   .L3
.L3:
        mov     rax, QWORD PTR [rdi+8]
        mov     rdi, r8
        mov     rax, QWORD PTR [rax]
        jmp     rax
```

This case may seem contrived, but it's not that rare in practice, because code
using std::variant or equivalent (such as Boost.Variant2, from which the
example has been reduced) is becoming more and more common nowadays.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-10-02 21:52 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-13  1:42 [Bug c++/98649] New: Trivial jump table not eliminated pdimov at gmail dot com
2021-01-13  5:35 ` [Bug middle-end/98649] " pinskia at gcc dot gnu.org
2021-01-13  8:10 ` marxin at gcc dot gnu.org
2021-10-02 21:52 ` pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).