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

            Bug ID: 77614
           Summary: Missed optimisation with -O3 when passing integral
                    type by constexpr using std::less(a,b) instead of b>a
           Product: gcc
           Version: 6.2.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gcc at 4z2 dot de
  Target Milestone: ---

Created attachment 39628
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39628&action=edit
Output with -v

I'm implementing SuperScalar Sample Sort, a sorting algorithm using (e.g.) 127
splitters to partition the input into 128 buckets. Elements' destination
buckets are found using a search in an Eytzinger layout tree: index = 2*index +
(key > splitters[index]). This step is implemented as a constexpr.

This works fine when using operator>, but switching to a templatized Compare
object (in this case, std::less<> with reversed operands) results in a missed
optimisation opportunity. There is a discussion with the generated assembly in
https://github.com/lorenzhs/ssssort/pull/8

The workaround is to pass 'key' by value instead of const reference if it's an
integral type (it would probably be better to use it for POD types with size up
to x bytes, but I digress):
https://github.com/lorenzhs/ssssort/pull/8/commits/9668c9fd53911250b40507767afd32ed3fdd457a
. This results in the same code being emitted as when passing by const ref and
comparing with operator>.

I'm running Debian unstable, gcc version 6.2.0 20160901 (Debian 6.2.0-3).
Compilation flags are "-std=c++14 -Wall -Wextra -Werror -march=native -O3 -g
-DNDEBUG".

Reply via email to