public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug tree-optimization/103733] New: Missed optimization: defaulted op== for trivially comparable types worse than memcmp
@ 2021-12-15 11:49 jengelh at inai dot de
  2021-12-15 12:37 ` [Bug tree-optimization/103733] " jakub at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: jengelh at inai dot de @ 2021-12-15 11:49 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 103733
           Summary: Missed optimization: defaulted op== for trivially
                    comparable types worse than memcmp
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jengelh at inai dot de
  Target Milestone: ---

== Input ==
struct S {
        char b[16];
#if __cplusplus >= 202000L
        bool operator==(const S &) const = default;
#else
        inline bool operator==(const S &o) const { return
__builtin_memcpy(const_cast<char *>(b), o.b, sizeof(b)); }
#endif
};
bool fff(const S &a, const S &b) { return a == b; }


== Observed ==
gcc version 12.0.0 20211214 973f6aedeb6489a9fdc7aeceaed0514348ee1e1a x86_64

$ ./xgcc -B. -c x.cpp -O2 -std=c++20 && objdump -d x.o
0000000000000000 <_Z3fffRK1SS1_>:
   0:   31 c0                   xor    %eax,%eax
   2:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
   8:   0f b6 14 06             movzbl (%rsi,%rax,1),%edx
   c:   38 14 07                cmp    %dl,(%rdi,%rax,1)
   f:   75 17                   jne    28 <_Z3fffRK1SS1_+0x28>
  11:   48 83 c0 01             add    $0x1,%rax
  15:   48 83 f8 10             cmp    $0x10,%rax
  19:   75 ed                   jne    8 <_Z3fffRK1SS1_+0x8>
  1b:   b8 01 00 00 00          mov    $0x1,%eax
  20:   c3                      ret    
  21:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)
  28:   31 c0                   xor    %eax,%eax
  2a:   c3                      ret  

== Expected ==
Expected the same result as when -std=c++17/memcmp is used.

0000000000000000 <_Z3fffRK1SS1_>:
   0:   f3 0f 6f 06             movdqu (%rsi),%xmm0
   4:   b8 01 00 00 00          mov    $0x1,%eax
   9:   0f 11 07                movups %xmm0,(%rdi)
   c:   c3                      ret

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

* [Bug tree-optimization/103733] Missed optimization: defaulted op== for trivially comparable types worse than memcmp
  2021-12-15 11:49 [Bug tree-optimization/103733] New: Missed optimization: defaulted op== for trivially comparable types worse than memcmp jengelh at inai dot de
@ 2021-12-15 12:37 ` jakub at gcc dot gnu.org
  2021-12-15 13:38 ` jengelh at inai dot de
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: jakub at gcc dot gnu.org @ 2021-12-15 12:37 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
You are using memcpy instead of memcmp in your testcase, which does something
very different...

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

* [Bug tree-optimization/103733] Missed optimization: defaulted op== for trivially comparable types worse than memcmp
  2021-12-15 11:49 [Bug tree-optimization/103733] New: Missed optimization: defaulted op== for trivially comparable types worse than memcmp jengelh at inai dot de
  2021-12-15 12:37 ` [Bug tree-optimization/103733] " jakub at gcc dot gnu.org
@ 2021-12-15 13:38 ` jengelh at inai dot de
  2021-12-15 13:50 ` jakub at gcc dot gnu.org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: jengelh at inai dot de @ 2021-12-15 13:38 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Jan Engelhardt <jengelh at inai dot de> ---
== New input ==
$ cat x.cpp
struct S {
        char b[16];
#if __cplusplus >= 202000L
        bool operator==(const S &) const = default;
#else
        inline bool operator==(const S &o) const { return __builtin_memcmp(b,
o.b, sizeof(b)); }
#endif
};
bool fff(const S &a, const S &b) { return a == b; }

== Observed ==
$ ./xgcc -B. -c /dev/shm/x.cpp -O2 && objdump -d x.o
0000000000000000 <_Z3fffRK1SS1_>: C++17
   0:   48 8b 17                mov    (%rdi),%rdx
   3:   48 8b 47 08             mov    0x8(%rdi),%rax
   7:   48 33 16                xor    (%rsi),%rdx
   a:   48 33 46 08             xor    0x8(%rsi),%rax
   e:   48 09 d0                or     %rdx,%rax
  11:   0f 95 c0                setne  %al
  14:   c3                      ret

0000000000000000 <_Z3fffRK1SS1_>: C++20
   0:   31 c0                   xor    %eax,%eax
   2:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
   8:   0f b6 14 06             movzbl (%rsi,%rax,1),%edx
   c:   38 14 07                cmp    %dl,(%rdi,%rax,1)
   f:   75 17                   jne    28 <_Z3fffRK1SS1_+0x28>
  11:   48 83 c0 01             add    $0x1,%rax
  15:   48 83 f8 10             cmp    $0x10,%rax
  19:   75 ed                   jne    8 <_Z3fffRK1SS1_+0x8>
  1b:   b8 01 00 00 00          mov    $0x1,%eax
  20:   c3                      ret    
  21:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)
  28:   31 c0                   xor    %eax,%eax
  2a:   c3                      ret

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

* [Bug tree-optimization/103733] Missed optimization: defaulted op== for trivially comparable types worse than memcmp
  2021-12-15 11:49 [Bug tree-optimization/103733] New: Missed optimization: defaulted op== for trivially comparable types worse than memcmp jengelh at inai dot de
  2021-12-15 12:37 ` [Bug tree-optimization/103733] " jakub at gcc dot gnu.org
  2021-12-15 13:38 ` jengelh at inai dot de
@ 2021-12-15 13:50 ` jakub at gcc dot gnu.org
  2021-12-16 13:44 ` jengelh at inai dot de
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: jakub at gcc dot gnu.org @ 2021-12-15 13:50 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
That is still not equivalent, I bet you meant return !__builtin_memcmp.

Anyway, the reason we can optimize memcmp and can't optimize the loop that the
defaulted operator== emits is that there is no guarantee that all the bytes can
be safely accessed if there is a difference in the bytes before it.
Say when a points to end of mmaped region with only 8 bytes mapped in it and
similarly for b.

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

* [Bug tree-optimization/103733] Missed optimization: defaulted op== for trivially comparable types worse than memcmp
  2021-12-15 11:49 [Bug tree-optimization/103733] New: Missed optimization: defaulted op== for trivially comparable types worse than memcmp jengelh at inai dot de
                   ` (2 preceding siblings ...)
  2021-12-15 13:50 ` jakub at gcc dot gnu.org
@ 2021-12-16 13:44 ` jengelh at inai dot de
  2021-12-16 21:53 ` [Bug c++/103733] Defaulted operator== for arrays of integral types could be done using memcmp instead of loop pinskia at gcc dot gnu.org
  2023-07-13 18:15 ` pinskia at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: jengelh at inai dot de @ 2021-12-16 13:44 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Jan Engelhardt <jengelh at inai dot de> ---
Is there a way to convey that it is safe to access every and all parts of S,
e.g. by initializing S::b at construction time?

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

* [Bug c++/103733] Defaulted operator== for arrays of integral types could be done using memcmp instead of loop
  2021-12-15 11:49 [Bug tree-optimization/103733] New: Missed optimization: defaulted op== for trivially comparable types worse than memcmp jengelh at inai dot de
                   ` (3 preceding siblings ...)
  2021-12-16 13:44 ` jengelh at inai dot de
@ 2021-12-16 21:53 ` pinskia at gcc dot gnu.org
  2023-07-13 18:15 ` pinskia at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-12-16 21:53 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|tree-optimization           |c++
           Keywords|                            |missed-optimization
           Severity|normal                      |enhancement
            Summary|Missed optimization:        |Defaulted operator== for
                   |defaulted op== for          |arrays of integral types
                   |trivially comparable types  |could be done using memcmp
                   |worse than memcmp           |instead of loop

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

* [Bug c++/103733] Defaulted operator== for arrays of integral types could be done using memcmp instead of loop
  2021-12-15 11:49 [Bug tree-optimization/103733] New: Missed optimization: defaulted op== for trivially comparable types worse than memcmp jengelh at inai dot de
                   ` (4 preceding siblings ...)
  2021-12-16 21:53 ` [Bug c++/103733] Defaulted operator== for arrays of integral types could be done using memcmp instead of loop pinskia at gcc dot gnu.org
@ 2023-07-13 18:15 ` pinskia at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-07-13 18:15 UTC (permalink / raw)
  To: gcc-bugs

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

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

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

--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Dup of bug 108953.

Even though PR 108953 is newer, it contains more details on how to fix this and
contains a few different/better testcases and such.

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

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

end of thread, other threads:[~2023-07-13 18:15 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-15 11:49 [Bug tree-optimization/103733] New: Missed optimization: defaulted op== for trivially comparable types worse than memcmp jengelh at inai dot de
2021-12-15 12:37 ` [Bug tree-optimization/103733] " jakub at gcc dot gnu.org
2021-12-15 13:38 ` jengelh at inai dot de
2021-12-15 13:50 ` jakub at gcc dot gnu.org
2021-12-16 13:44 ` jengelh at inai dot de
2021-12-16 21:53 ` [Bug c++/103733] Defaulted operator== for arrays of integral types could be done using memcmp instead of loop pinskia at gcc dot gnu.org
2023-07-13 18:15 ` 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).