public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/95383] New: Poor codegen when constructing a trivial Optional
@ 2020-05-28 13:56 barry.revzin at gmail dot com
  2020-05-29  6:21 ` [Bug c++/95383] " rguenth at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: barry.revzin at gmail dot com @ 2020-05-28 13:56 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 95383
           Summary: Poor codegen when constructing a trivial Optional
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: barry.revzin at gmail dot com
  Target Milestone: ---

Here is a complete example:

struct nullopt_t {} inline constexpr nullopt{};

template <typename T>
struct Optional {
    struct Empty { };
    union {
        Empty _;
        T value;
    };
    bool engaged;

    Optional(nullopt_t) : _(), engaged(false) { }
    Optional(T v) : value(v), engaged(true) { }
};

Optional<int> foo(bool b) {
    if (b) {
        return 42;
    }
    return nullopt;
}

Optional here is a valid implementation strategy for trivial types, like int.
You can see some codegen examples here: https://godbolt.org/z/KwuWzB

gcc 10.1 -O2 emits:

foo(bool):
        test    dil, dil
        mov     eax, 0
        movabs  rdx, 4294967338
        cmovne  rax, rdx
        ret

gcc 10.1 -O3 is worse:

foo(bool):
        xor     eax, eax
        mov     ecx, 42
        test    dil, dil
        cmovne  rdx, rcx
        mov     ecx, 1
        cmovne  rax, rcx
        movabs  rcx, -1095216660481
        and     rdx, rcx
        sal     rax, 32
        or      rax, rdx
        ret

gcc trunk (as of today) -O2 is the same as this bad -O3 version.

clang 10, on the other hand, on -O2 or -O3, emits:

foo(bool):                                # @foo(bool)
        shl     rdi, 32
        lea     rax, [rdi + 42]
        ret

which is much better. 

Using std::optional instead of this Optional (https://godbolt.org/z/By-fYx) for
comparison, clang emits the same code as above. gcc 10 -O3 emits a branch:

foo(bool):
        xor     eax, eax
        test    dil, dil
        je      .L2
        mov     DWORD PTR [rsp-8], 42
        mov     eax, 1
.L2:
        mov     BYTE PTR [rsp-4], al
        mov     rax, QWORD PTR [rsp-8]
        ret

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

* [Bug c++/95383] Poor codegen when constructing a trivial Optional
  2020-05-28 13:56 [Bug c++/95383] New: Poor codegen when constructing a trivial Optional barry.revzin at gmail dot com
@ 2020-05-29  6:21 ` rguenth at gcc dot gnu.org
  2021-12-17  5:33 ` [Bug middle-end/95383] " pinskia at gcc dot gnu.org
  2023-07-12 21:35 ` pinskia at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-05-29  6:21 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jamborm at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org
           Keywords|                            |missed-optimization
   Last reconfirmed|                            |2020-05-29
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
I see the cited -O3 code-gen with -O2 on trunk.  We expand from

foo (bool b)
{
  struct Optional D.2251;
  unsigned char _7;

  <bb 2> [local count: 1073741824]:
  if (b_2(D) != 0)
    goto <bb 3>; [50.00%]
  else
    goto <bb 4>; [50.00%]

  <bb 3> [local count: 536870913]:
  D.2251.D.2152.value = 42;

  <bb 4> [local count: 1073741824]:
  # _7 = PHI <1(3), 0(2)>
  MEM <unsigned char> [(struct Optional *)&D.2251 + 4B] = _7;
  return D.2251;

where the main issue is likely we fail to elide D.2251 because of the
aggregate return (and us not exposing the ABI, etc.).

Note above D.2251 is partly initialized which makes it a bit more difficult
to optimize.  SRA might try to handle these cases by rematerializing the
aggregate just before the return.  We can then hope for RTL expansion
to do "magic".

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

* [Bug middle-end/95383] Poor codegen when constructing a trivial Optional
  2020-05-28 13:56 [Bug c++/95383] New: Poor codegen when constructing a trivial Optional barry.revzin at gmail dot com
  2020-05-29  6:21 ` [Bug c++/95383] " rguenth at gcc dot gnu.org
@ 2021-12-17  5:33 ` pinskia at gcc dot gnu.org
  2023-07-12 21:35 ` pinskia at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-12-17  5:33 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|c++                         |middle-end
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=95405,
                   |                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=101326
             Blocks|                            |101926
           Severity|normal                      |enhancement


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101926
[Bug 101926] [meta-bug] struct/complex argument passing and return should be
improved

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

* [Bug middle-end/95383] Poor codegen when constructing a trivial Optional
  2020-05-28 13:56 [Bug c++/95383] New: Poor codegen when constructing a trivial Optional barry.revzin at gmail dot com
  2020-05-29  6:21 ` [Bug c++/95383] " rguenth at gcc dot gnu.org
  2021-12-17  5:33 ` [Bug middle-end/95383] " pinskia at gcc dot gnu.org
@ 2023-07-12 21:35 ` pinskia at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-07-12 21:35 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |DUPLICATE

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Dup.

*** This bug has been marked as a duplicate of bug 95405 ***

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

end of thread, other threads:[~2023-07-12 21:35 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-28 13:56 [Bug c++/95383] New: Poor codegen when constructing a trivial Optional barry.revzin at gmail dot com
2020-05-29  6:21 ` [Bug c++/95383] " rguenth at gcc dot gnu.org
2021-12-17  5:33 ` [Bug middle-end/95383] " pinskia at gcc dot gnu.org
2023-07-12 21:35 ` 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).