https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125365
Bug ID: 125365
Summary: Missed optimization: duplicate calls to function
declared as pure
Product: gcc
Version: 15.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: jjk at acm dot org
Target Milestone: ---
Created attachment 64485
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=64485&action=edit
Original unpreprocessed source
The attached example code exposes a missed optimization opportunity.
- Class FOO has a member function declared as "pure", which returns an integer
given an index.
- Class BAR is a wrapper for FOO whose own member function calls FOO's member
twice for adjacent indices, shifting and combining the return values.
- Class BAZ holds an array of integers which is initialized by calling BAR's
member function for consecutive indices.
The code generated by GCC (for versions from at least 14.2.1 to the current
"trunk" version visible on Compiler Explorer) calls the "pure" FOO::operator[]
8 times, with arguments 0, 1, 1, 2, 2, 3, 3, 4. In contrast, code generated by
Clang calls it only 5 times, with arguments 0, 1, 2, 3, 4.
When the code is compiled with -DWORKAROUND=1, an alternative version of BAZ's
constructor is used, which builds a temporary array and assigns it BAZ's member
variable at the end. GCC versions up to and including 15.1 generate more
efficient code for this version, effectively identical to the result produced
by Clang. However, GCC versions 15.2 and later *always* generate the less
efficient version of the code.
Compiler Explorer links:
- GCC 15.1, no workaround: https://godbolt.org/z/e9jWh4qfb
- GCC 15.1 with workaround: https://godbolt.org/z/Pfdve6YW3 (improvement)
- GCC 15.2 with workaround: https://godbolt.org/z/Yo7fd7b1M (no improvement)
- Clang: https://godbolt.org/z/GMecqWda4