Issue 139995
Summary Cannot reproduce object on one architecture by cross-compiling on another with -flto=thin
Labels new issue
Assignees
Reporter iskunk
    This is an issue discovered in the course of cross-compiling Chromium. I am attempting to reproduce, bit-for-bit, a native x86-64 Linux build of Chromium by cross-compiling it from a different Linux architecture. If I do not use LTO, then this works as intended: all the resulting x86-64 objects, libraries, and executables match exactly on both systems. If I specify `-flto=thin`, however, then I get different outputs on the two architectures, starting with `.o` files. The output is still deterministic within each architecture, but of course I want to see output that is the same irrespective of the build system.

I have verified this issue using the project's pre-compiled binaries of LLVM 20.1.5 for X64 and ARM64. I don't have an ARM hardware system, so I used a Docker ARM64 container running via QEMU. My test environment was Ubuntu 25.04/plucky, one instance on amd64, another on arm64. The latter has appropriate cross-compilation packages installed, e.g. `libstdc++-14-dev-amd64-cross`. (Note that I originally encountered this issue in a cross build from ppc64el, but no upstream LLVM binaries are available for that platform.)

Here is a small "kit" to reproduce the problem:

[cross-test.zip](https://github.com/user-attachments/files/20219132/cross-test.zip)

It uses a cut-down source file `spinlock.cc` (plus its dependencies) taken from Chromium, since the issue does not occur with a trivial "hello world"-type program. This file was chosen as it is relatively simple, and was among the first ones to come out differently between the two builds. There is a makefile with a small set of compiler flags that allow the preprocessed source output to match exactly regardless of whether the source is being compiled natively on x86-64, or cross-compiled from ARM64. Running `make CXX=/path/to/clang++` will show the MD5-hashed results of compiling the source file.

Here is the output I see on the amd64 system:
```
$ make clean; make CXX=/opt/llvm/bin/clang++ 
rm -f spinlock spinlock.dep spinlock.ii spinlock.o
/opt/llvm/bin/clang++ --target=x86_64-unknown-linux-gnu -I. --no-line-commands -ffile-prefix-map=/usr/bin/../lib/gcc-cross/=/usr/bin/../lib/gcc/ -ffile-prefix-map=/usr/bin/../lib/gcc-cross/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/=/usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../ -flto=thin -c spinlock.cc
/opt/llvm/bin/clang++ --target=x86_64-unknown-linux-gnu -I. --no-line-commands -ffile-prefix-map=/usr/bin/../lib/gcc-cross/=/usr/bin/../lib/gcc/ -ffile-prefix-map=/usr/bin/../lib/gcc-cross/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/=/usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../ -flto=thin -E spinlock.cc >spinlock.ii
ls -l spinlock.o
-rw-r--r-- 1 build users 4276 May 15 03:06 spinlock.o
7eee0e28d709caf76f71a2b249eef3b8 spinlock.cc
3120df26bdad524adbb170fa4c635be7 spinlock.cc.orig
3737b72697300f721ef4c52ebfe109ed spinlock.ii
2f2cc887fc8dee159ed401da301d387c  spinlock.o
```

And then on arm64:
```
$ make clean; make CXX=/opt/llvm/bin/clang++ 
rm -f spinlock spinlock.dep spinlock.ii spinlock.o
/opt/llvm/bin/clang++ --target=x86_64-unknown-linux-gnu -I. --no-line-commands -ffile-prefix-map=/usr/bin/../lib/gcc-cross/=/usr/bin/../lib/gcc/ -ffile-prefix-map=/usr/bin/../lib/gcc-cross/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/=/usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../ -flto=thin -c spinlock.cc
/opt/llvm/bin/clang++ --target=x86_64-unknown-linux-gnu -I. --no-line-commands -ffile-prefix-map=/usr/bin/../lib/gcc-cross/=/usr/bin/../lib/gcc/ -ffile-prefix-map=/usr/bin/../lib/gcc-cross/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/=/usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../ -flto=thin -E spinlock.cc >spinlock.ii
ls -l spinlock.o
-rw-r--r-- 1 build users 4276 May 15 03:03 spinlock.o
7eee0e28d709caf76f71a2b249eef3b8 spinlock.cc
3120df26bdad524adbb170fa4c635be7 spinlock.cc.orig
3737b72697300f721ef4c52ebfe109ed spinlock.ii
af549dab0aa1daafdfcec288defc4a72  spinlock.o
```

Notice how the preprocessed output (`.ii`) is identical on both systems, yet the compiled object (`.o`) is not. For inspection purposes, I've placed both object files in this archive:

[spinlock-objects.zip](https://github.com/user-attachments/files/20219174/spinlock-objects.zip)

And in case it is needed, here is the preprocessed source:

[spinlock.ii.txt](https://github.com/user-attachments/files/20219239/spinlock.ii.txt)
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to