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

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

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

asolokha at gmx dot com
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.
Reply | Threaded
Open this post in threaded view
|

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

asolokha at gmx dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87952

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
I belive I've seen dups for this.  We merely isolate those paths but do not
remove them (removing them might end up as a security issue).