public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug ipa/114784] New: [14 Regression] Inlining fails for always_inline inheriting constructor
@ 2024-04-19 20:05 dani at danielbertalan dot dev
  2024-04-19 20:08 ` [Bug ipa/114784] " dani at danielbertalan dot dev
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: dani at danielbertalan dot dev @ 2024-04-19 20:05 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 114784
           Summary: [14 Regression] Inlining fails for always_inline
                    inheriting constructor
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: ipa
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dani at danielbertalan dot dev
  Target Milestone: ---

The code below has been reduced from SerenityOS's custom std::variant-like
type. Its constructors are implemented by recursively inheriting from a helper
class which adds a constructor that can take one of the stored types. This,
however, creates a bunch of small constructors - each of which just end up
calling into the set<T>() method - which don't necessarily get inlined. Our
measurements showed that we can achieve up to 20% reduction in the run time of
our test suite by marking these as __attribute__((always_inline)). (Like in
most other similar issues, inlining is not a matter of correctness for us, we
just want to overrule inlining heuristics).

Ever since the GCC trunk of summer 2023, we have been getting compile errors
about failing to inline these constructors ("call is unlikely and code size
would grow"). Below is the smallest reproducer we could create for this issue
(admittedly, it has UB, so not sure if it's the exact same issue as in the real
code). Note that if we explicitly write out the constructor instead of
inheriting it (even if it does the same thing), as shown by the long long
overloads below, the issue goes away (compile with -std=c++20 -O2).

See: https://godbolt.org/z/5hb584T9r

---

template <typename Base>
struct VariantConstructors {
  __attribute__((always_inline)) VariantConstructors(int t) {
    base().set(t, {});
  }
  __attribute__((always_inline)) VariantConstructors(long long t) {
    base().set(t, {});
  }
  Base base();
};

struct Variant : VariantConstructors<Variant> {
  using VariantConstructors<Variant>::VariantConstructors;

  __attribute__((always_inline)) Variant(long long v) : VariantConstructors(v)
{}

  template <typename T> void set(T &&, int);
  char m_data;
};

struct ErrorOr {
  ErrorOr(int v) : a(v) { }
  ErrorOr(long long v) : a(v) { }
  Variant a;
};
static ErrorOr run() {
  ErrorOr x(0); // compiles with this line removed
  ErrorOr y(0LL);
  return 0;
}
int serenity_main() {
    run();
}

---

gcc -v output:

GNU C++20
(Compiler-Explorer-Build-gcc-85c187b2127b937e211dfe46b4120d320ff661df-binutils-2.40)
version 14.0.1 20240419 (experimental) (x86_64-linux-gnu)
        compiled by GNU C version 11.4.0, GMP version 6.2.1, MPFR version
4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP

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

end of thread, other threads:[~2024-04-23  6:40 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-19 20:05 [Bug ipa/114784] New: [14 Regression] Inlining fails for always_inline inheriting constructor dani at danielbertalan dot dev
2024-04-19 20:08 ` [Bug ipa/114784] " dani at danielbertalan dot dev
2024-04-19 20:21 ` jakub at gcc dot gnu.org
2024-04-19 20:42 ` jakub at gcc dot gnu.org
2024-04-19 21:07 ` jakub at gcc dot gnu.org
2024-04-19 22:00 ` dani at danielbertalan dot dev
2024-04-22 11:14 ` jakub at gcc dot gnu.org
2024-04-23  6:39 ` cvs-commit at gcc dot gnu.org
2024-04-23  6:40 ` jakub 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).