llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.64k stars 11.37k forks source link

Sub-optimal code generation for the spaceship (`<=>`) operator #98148

Open loskutov opened 1 month ago

loskutov commented 1 month ago

Consider the following simple example (compiler explorer):

struct Triple {
    uint64_t first;
    uint64_t second;
    uint64_t third;
// first option: hand-written member-wise comparison (for e.g. sorting, only operator< is needed)
    bool operator<(const Triple& rhs) const {
        if (first != rhs.first)
            return first < rhs.first;
        if (second != rhs.second)
            return second < rhs.second;
        return third < rhs.third;
    }
// second option: compiler-generated spaceship operator
    auto operator<=>(const WithSpaceship&) const = default;
};

Apparently, the generated code for the hand-written less-than comparison is better: the setb is only performed before the actual return, and the benchmarks show that it is indeed faster. I would expect the compiler-generated comparison to be at least as fast so that it doesn't discourage adopting operator<=>.

llvmbot commented 1 month ago

@llvm/issue-subscribers-clang-codegen

Author: Ignat Loskutov (loskutov)

Consider the following simple example ([compiler explorer](https://godbolt.org/z/Tx6j7rcMo)): ```cpp struct Triple { uint64_t first; uint64_t second; uint64_t third; // first option: hand-written member-wise comparison (for e.g. sorting, only operator< is needed) bool operator<(const Triple& rhs) const { if (first != rhs.first) return first < rhs.first; if (second != rhs.second) return second < rhs.second; return third < rhs.third; } // second option: compiler-generated spaceship operator auto operator<=>(const WithSpaceship&) const = default; }; ``` Apparently, the generated code for the hand-written less-than comparison is better: the `setb` is only performed before the actual return, and the benchmarks show that it is indeed faster. I would expect the compiler-generated comparison to be at least as fast so that it doesn't discourage adopting `operator<=>`.