This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/87952] New: Missed optimization for std::get_if on std::variant


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

            Bug ID: 87952
           Summary: Missed optimization for std::get_if on std::variant
           Product: gcc
           Version: 8.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: narut.se at gmail dot com
  Target Milestone: ---

Here is the sample code:

#include <variant>

int test(std::variant<int, bool> &v)
{
    return *std::get_if<int>(&v);
}


gcc generates (on x86-64):

test(std::variant<int, bool>&):
        cmp     BYTE PTR [rdi+4], 0
        jne     .L2
        mov     eax, DWORD PTR [rdi]
        ret
test(std::variant<int, bool>&) [clone .cold]:
.L2:
        mov     eax, DWORD PTR ds:0
        ud2

It seems like the undefined behavior branch can be optimized away leaving (as
clang does):

test(std::variant<int, bool>&):               # @test(std::variant<int, bool>&)
        mov     eax, dword ptr [rdi]
        ret


The reason this is useful is that if I know ahead of time (but the compiler
can't prove) that the variant holds a certain alternative, calling get_if this
way will provide no overhead access to the alternative. (The standard doesn't
allow this kind of access for std::get.) Since dereferencing the null pointer
(as would happen if the variant didn't hold the alternative) is undefined
behavior anyway, we could optimize it away and assume that the alternative is
valid.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]