llvm / llvm-project

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

incompatibility between unified LTO and ffat-lto-objects #90857

Open Matthieu-Sauer opened 5 months ago

Matthieu-Sauer commented 5 months ago

I tried to use the new -ffat-lto-objects feature from clang & lld 18, and it did seem that it was working (in flto full I was linking with a similar time as for lto thin, and lto thin links at the speed of no lto).

So I tried the unified LTO pipeline, as I saw discussions about perhaps making it mandatory for fat lto.

The combination of the two yelds the following result: Screenshot_20240502_155847

(this has been done on a personal project modified to allow for the lto to be used).

Steps to reproduce should be:

Take an existing project use an LLVM 18 pipeline on it (clang18 + lld18 + llvm-ar18) activate lto optimisations (full / thin, does not matter) activate -ffat-lto-objects & -funified-lto

now, lld complains about missing symbols. Symbols do exist outside of this configuration (remove unified / fat lto and the project compiles fine).

tested on a debian sid, with llvm 18.1.4 (provided by debian, not manually compiled) tested on following project: https://gitlab.com/azkalaak/zenith/ (main branch has not been pushed with the lto modifications, so if any testing needs to happen, the cmakelist should be modified).

perhaps i'm wrong to try this and the two options should not be activated at the same time?

Matthieu-Sauer commented 4 months ago

if needed, here is a minimal reproducible example:

// file1.cpp
#include "file1.hpp"

base::~base() {}

void base::fun1() {}

// file1.hpp
class base {
  public:
  virtual ~base();

  virtual void fun1();
};

// file2.hpp
#include "file1.hpp"

class child : public base {
  public:
    ~child() = default;

    void fun1() override {}
};

// main.cpp
#include "file2.hpp"

int main()
{
  child c;
  return 1;
}

Compilation command: clang++-18 main.cpp file1.cpp -o prog -flto -ffat-lto-objects -fuse-ld=lld-18

gorloffslava commented 1 week ago

We experience the same issue with v20git in a few packages. One notable example - building upstream Rust from sources. It works fine w/ only fat-lto-objects OR only unified-lto but with both crashes with similar vtable error.