public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/104632] New: Missed optimization about backward reads
@ 2022-02-22 8:36 lh_mouse at 126 dot com
2022-02-22 8:46 ` [Bug tree-optimization/104632] Missed optimization about reading backwards pinskia at gcc dot gnu.org
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: lh_mouse at 126 dot com @ 2022-02-22 8:36 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104632
Bug ID: 104632
Summary: Missed optimization about backward reads
Product: gcc
Version: 11.2.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: lh_mouse at 126 dot com
Target Milestone: ---
Target: x86_64-linux-gnu
This is a piece of code that has been simplified from a Boyer-Moore-Horspool
implementation:
https://gcc.godbolt.org/z/766GYM8xf
```c++
// In real code this was
// `load_le32_backwards(::std::reverse_iterator<const unsigned char*> ptr)
unsigned
load_le32_backwards(const unsigned char* ptr)
{
unsigned word = ptr[-1];
word = word << 8 | ptr[-2];
word = word << 8 | ptr[-3];
word = word << 8 | ptr[-4];
return word;
}
```
This is equivalent to `return ((unsigned*)ptr)[-1];` on x86_64, but GCC fails
to optimize it:
GCC output:
```
load_le32_backwards(unsigned char const*):
movzx edx, BYTE PTR [rdi-1]
movzx eax, BYTE PTR [rdi-2]
sal edx, 8
or eax, edx
movzx edx, BYTE PTR [rdi-3]
sal eax, 8
or edx, eax
movzx eax, BYTE PTR [rdi-4]
sal edx, 8
or eax, edx
ret
```
Clang output:
```
load_le32_backwards(unsigned char const*): #
@load_le32_backwards(unsigned char const*)
mov eax, dword ptr [rdi - 4]
ret
```
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug tree-optimization/104632] Missed optimization about reading backwards
2022-02-22 8:36 [Bug c++/104632] New: Missed optimization about backward reads lh_mouse at 126 dot com
@ 2022-02-22 8:46 ` pinskia at gcc dot gnu.org
2022-02-22 9:19 ` lh_mouse at 126 dot com
2022-02-22 10:39 ` rguenth at gcc dot gnu.org
2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-02-22 8:46 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104632
Andrew Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Severity|normal |enhancement
Component|c++ |tree-optimization
--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
There might be another bug that is similar to this.
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug tree-optimization/104632] Missed optimization about reading backwards
2022-02-22 8:36 [Bug c++/104632] New: Missed optimization about backward reads lh_mouse at 126 dot com
2022-02-22 8:46 ` [Bug tree-optimization/104632] Missed optimization about reading backwards pinskia at gcc dot gnu.org
@ 2022-02-22 9:19 ` lh_mouse at 126 dot com
2022-02-22 10:39 ` rguenth at gcc dot gnu.org
2 siblings, 0 replies; 4+ messages in thread
From: lh_mouse at 126 dot com @ 2022-02-22 9:19 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104632
--- Comment #2 from LIU Hao <lh_mouse at 126 dot com> ---
I don't think it's a duplicate. This only happens when reading through a
pointer by negative offsets. If I change the code to read by non-negative
offsets, GCC is actually very happy about it:
https://gcc.godbolt.org/z/sT9hzcndW
```
// In real code this was
// `load_le32_backwards(::std::reverse_iterator<const unsigned char*> ptr)
unsigned
load_le32_backwards(const unsigned char* ptr)
{
unsigned word = ptr[3];
word = word << 8 | ptr[2];
word = word << 8 | ptr[1];
word = word << 8 | ptr[0];
return word;
}
```
```
load_le32_backwards(unsigned char const*):
mov eax, DWORD PTR [rdi]
ret
```
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug tree-optimization/104632] Missed optimization about reading backwards
2022-02-22 8:36 [Bug c++/104632] New: Missed optimization about backward reads lh_mouse at 126 dot com
2022-02-22 8:46 ` [Bug tree-optimization/104632] Missed optimization about reading backwards pinskia at gcc dot gnu.org
2022-02-22 9:19 ` lh_mouse at 126 dot com
@ 2022-02-22 10:39 ` rguenth at gcc dot gnu.org
2 siblings, 0 replies; 4+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-02-22 10:39 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104632
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Ever confirmed|0 |1
Last reconfirmed| |2022-02-22
Status|UNCONFIRMED |NEW
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
The bswap pass is supposed to handle these but has
bool
find_bswap_or_nop_load (gimple *stmt, tree ref, struct symbolic_number *n)
{
...
/* Avoid returning a negative bitpos as this may wreak havoc later. */
if (maybe_lt (bit_offset, 0))
{
commenting the code produces the desired
load_le32_backwards:
.LFB0:
.cfi_startproc
movl -4(%rdi), %eax
ret
the code is present since the introduction of memory source to the bswap pass.
It needs to be investigated what exactly the "havoc" is but clearly the "havoc"
should be mitigated closer to the offenders since the above case seems to work
just fine.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-02-22 10:39 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-22 8:36 [Bug c++/104632] New: Missed optimization about backward reads lh_mouse at 126 dot com
2022-02-22 8:46 ` [Bug tree-optimization/104632] Missed optimization about reading backwards pinskia at gcc dot gnu.org
2022-02-22 9:19 ` lh_mouse at 126 dot com
2022-02-22 10:39 ` rguenth 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).